with a Special Section on the Timex/Sinclair 2000
THE ESSENTIAL GUIDE TÜ
TIMEX/SINCLAIR
HOME COMPUTERS
! The Only Book You'll Ever Need to Become an
| Expert at the Timex/Sinclair 1000 and 2000
li
ЖДД ЕТП
: f
"d
cundo 3H YIVIINIS/KIWIL
ñ. E 1 ' Е E
МУГ ы ЕК
ie L E S M 4 % 5 | а
\ ( ' “ [| | li ( ү ж | я , TY 7 ` `
| E 4 є d] j = у | et Ties | А | E
ч т, d x I ^ ; s a | -
EN А Gs >
i E»: "A
"v 4
y "4p".
THE ESSENTIAL GUIDE TO
TIMEX/SINCLAIR
HOME COMPUTERS
The Only Book You'll Ever Need
to Become an Expert
at the Timex/Sinclair 1000 and 2000
by
PETER MORSE, IAN ADAMSON
BEN ANREP and BRIAN HANCOCK
A TOUCHSTONE BOOK
Published by Simon & Schuster, Inc.
NEW YORK
We are grateful to Sinclair Research for their cooperation
This book was published in England under the title The Century
Computer Programming Course
Copyright © 1983 by Eosoft
All rights reserved
including the right of reproduction
in whole or in part in any form
A Touchstone Book
Published by Simon & Schuster, Inc.
Simon & Schuster Building
Rockefeller Center
1230 Avenue of the Americas
New York, New York 10020
Published by arrangement with Century Publishing
Company, England
TOUCHSTONE and colophon are registered trademarks of
Simon & Schuster, Inc.
Manufactured in the United States of America
10 98 765 43 2 1 Pbk.
Library of Congress Cataloging in Publication Data
Main entry under title:
The Essential guide to Timex/Sinclair home computers.
(A Touchstone book)
British ed. published as: The century computer programming course.
1. Timex 1000 (Computer)—Programming. 2. Timex Sinclair 2000
(Computer)—Programming. 3. Basic (Computer program
language) I. Morse, Peter (Peter L. R.) II. Title.
QA76.8.T48E77 1983 001.64'2 83-9090
ISBN 0-671-47069-8 Pbk.
IMPORTANT NOTE FOR ALL READERS
This book uses the Sinclair version of single keystroke BASIC as
featured on the ZX81 and Spectrum microcomputers. In the States the
ZX81 has been marketed as the Timex/Sinclair 1000 and the
Spectrum is known as the Timex/Sinclair 2000. American readers
should note that throughout the text we refer to these machines by their
UK names. There are a few minor differences between the UK version
of the ZX81 and the US TS 1000. The first is that the TS 1000 has
more ‘on board’ memory (2k) than its UK equivalent. However, this is
still insufficient for the scope of this text, and the majority of the
programs occurring in the book will require a 16k RAM pack. The
second difference is that two keys, which do exactly the same thing, are
labelled differently. Thus, NEWLINE and ENTER are equivalent on
the ZX81 and the TS 1000, as are RUBOUT and DELETE. On each
occasion that these commands occur in the text, readers will find either
NEWLINE (ENTER) or RUBOUT (DELETE).
For the sake of clarity we have used the ZX81/TS 1000 version of
BASIC as the foundation of the book, and have noted those instances
where Spectrum (TS 2000) BASIC differs from that used by the ZX81
(TS 1000). Functions and commands exclusive to the Spectrum (TS
2000) BASIC superset are fully explained at the end of the book (Units
W2 and W3).
In short, the book has been designed to enable its readers to learn
how to program using any of the Sinclair machines.
Users of the Spectrum should note that all programs are listed in
capital letters throughout. To get program results and listings that look
identical to those given here the capital letter (CAPS) mode must be
used on the Spectrum for all letters input or printed. The first two
Units of Part One deal only with the ZX81. The Spectrum user should
read instead Unit W1 (page 439) of the Spectrum dedicated Section
which forms Part Five of this text.
TE
РЧ КЛ АЙ oie SOT TOM ГИЛ ГАГИ
í; FAD iin “ger former үніне” wh еи фе” ИЯ?
= ez deus qo +. теі Craft <p dj Lente ' ` лу me imos
чї Мг» ОҒ” tint G ete ГГ м” +, бағала Cow sa ТЕК
«rues scores НЕ qub uncuoncul wit а nmond W (tre
ИЛЕ ow ai z p Op ron HE ыы. sec anda ses ФИИ»
twee S cigs о of Ohh roues xml en Ж!)
qi NyEL. x м mh n pert of] GONE < T т. si are BM ani b.
4 nd: wywal aaarnas AF on amn ri yea bear fo оса)
яй 6 ышы нір Куе ЯҰ woli ba урт» wh) аа sailon Hor
Wh idea MIO кч „шшр |І) Vest wll i pen ун» АЫ
ө.ж”, ӘР diliang i dial, of «4 a1 64 bt шут ЇЙ, wane
hoe {йз етю 6 APPAR һа, 771249 145 Ant dherek Баъ
Ao ore? Fe 0 (has ТИТЛ 113 92:9 NODI VV йз 183 рм
‚2; d mb e: „і Waq; үт л ыз Ыл —2 боза" Ted onda М)
«ІЛМЕ РБЬӨГІЯ- тұр n TOELIWSƏ
bite ote VUE *+ et x уй іу” vu үз ques ne der чу e
жүз, SO k n ffm, (is /4 % .л.ілыкт wp ee "ul
1» 477 how Yani Ch. trace “ҰРТ Kin: 4 QUITE чи ЫЫ ey
5%% “Мз. é OF a $n» vy TIME 71 m і unie 1469! at
we 132 — 4 quies b oO ізнігіп iios suus ЯРЛЯ AON
4 pis SW
Y vnum & Айды!) Paige S=) a ved ¿P өсік ті
И айел Heine, wtih у, Эл потр Н Qam
4 ood boue sg dr ei іл. Oni шр че att 6. nme
мұ», 4 À) * уй Пул vndas ac) чода, er vm 49»
ы) wh * gop cm Fe . Á p? - M" Ж 4% el ба) „ aml 2), te darmi
LU EP "d Ris $ nf += == E | 2998 wi! 7", бузат
биз с» uar а” © M* pt die Laus 240 - of =n mae
4 E m. il Т” 1: m ( f 1:31 І а €2 Js gyi
a F 7“ 41 y - cl * m.
CONTENTS
page
Introduction xiii
PART ONE
FIRST STEPS xvii
SECTIONA THEZX81 MICROCOMPUTER SYSTEM l
А! 7Х81 System Description
A2 Function of Components +
SECTIONB GETTING TO KNOW THE ZX81 7
ВІ Connecting Up
B2 Тһе Keyboard 9
B3 Cursors 10
B4 ‘The Different Character Types 12
SECTION C BASIC BASIC 19
СІ Тһе BASIC Language 19
C2 А Simple Program 19
СЗ AStatement 20
C4 Statement Numbers 20
C5 Instructions 21
C6 Numeric Variables 21
C7 Strings and String Variables 23
C8 Operators and Operands 24
C9 Format of Statements 24
C10 Keying in a Statement 24
C11 Correcting Errors 26
C12 Commands 27
C13 Editing the Program 28
C14 Listing a Program on the Screen 29
C15 Running the Program 29
C16 Error Messages 31
C17 How the Program Works 32
C18 Naming the Program 33
SECTIOND SAVING, LOADING AND LISTING PROGRAMS 35
D1 Saving the Program on Cassette Tape 35
D2 Deleting the Program from Memory 38
D3 Loading the Program from Cassette Tape 40
vii
D4
D5
Listing the Program on the Printer
Program Libraries and Directories
SECTIONE IMPROVING THE PROGRAM
El
Е2
ЕЗ
Е4
Е5
E6
Adding Comments
Using the Print Statement
Adding a Loop
Stopping the Program
Testing for a Condition
Final Edit and Saving
SECTION F A GAME INTERLUDE
El
F2
The Program Library
A Game to Key In
PART TWO
ESSENTIALS OF BASIC PROGRAMMING
SECTION G PROGRAMMING METHODS I
G1
G2
G3
G4
G5
G6
G7
G8
G9
G10
Programming
Problem Analysis
Structure Diagrams
Classifying Program Modules
Control Structures
The Data Table
Describe the Algorithm
The Pseudocode Description
Flowcharts
Testing the Algorithm
SECTIONH CONTROL
H1
H2
H3
H4
H5
H6
Control in Programs
Condition Testing
IF-THEN
GOTO Instructions
Decision Structures
Logical Operators: AND/OR
SECTIONI PRINTING
I1
I2
PRINT/LPRINT
Spacing Items on the Screen
viii
57
43
44
46
46
46
47
48
49
51
53
53
53
59
59
60
63
65
67
70
72
73
74
84
86
86
86
87
88
89
96
99
99
100
ІЗ
14
РКІМТАТ
Тһе Graphics Characters оп (һе ZX81
SECTION J ARITHMETIC AND FUNCTIONS
Ji
J2
J3
J4
JS
J6
J7
18
19
Ј10
wil
112
113
Arithmetic Operations
Priority
Number
The E Notation
Rounding
How Numbers are Handled
Function
List of Functions in Sinclair BASIC
The Function Characters
The Function Character Set
The Standard Mathematical Functions
Trigonometric Functions
Special Functions
SECTION K STRINGS
K1
K2
K3
K4
K5
K6
K7
K8
K9
K10
K11
K12
Strings
Quotes and Quote Image
String Input
Length of a String
Null Strings
String and String Array Variables
String and String Array Dimension
String and String Array Assignment
Substrings and String Slices
String Concatenation
Comparing Strings
Strings and Numbers
SECTION L LOOPS
L1
L2
L3
L4
L5
Loops
Counters
FOR-NEXT Loops
Loops of Variable Length
Nested Loops
SECTIONM PLOTTING
MI
M2
PLOT and UNPLOT
Graph Plotting
IX
102
104
108
108
108
111
111
114
115
116
117
118
119
120
122
123
126
126
127
128
130
130
131
131
132
133
135
136
139
142
142
143
147
153
155
159
159
162
SECTIONN SUBROUTINES
N1
N2
N3
N4
N5
N6
Subroutines
Subroutine Example
Nested Subroutines
Recursive Subroutines
Computed GOSUBs
Subroutine Use: Example
PART THREE
ADVANCED BASIC PROGRAMMING
SECTIONO PROGRAMMING METHODS II
Ol
O2
O3
O4
O5
SECTION P THE CHARACTER SET AND CODES
Р1
P2
P3
P4
Resume
Producing the Program
Coding and Design
Program Development
The Complete Programming Method
The ZX81 Character Set and Codes
The Spectrum Character Set and Codes
Characters
CHR$ and CODE
SECTION Q GRAPHICS
O1
Q2
Q3
Q4
More Printing
More Plotting
Movement and Timing
The Display File
SECTION R LOGICAL OPERATIONS
R1
R2
R3
R4
R5
R6
R7
R8
R9
R10
Logical Values and Numeric Values
Boolean Operators: The AND Operator
The OR Operator
The NOT Operator
Conditional Operators
Logical Operations on Conditional Expressions
Multiple Logic on Conditions
Logical Operations on Numbers
Priority
Logical Operations with Strings
X
169
169
170
172
172
177
179
R11 Logical Operations Between Strings and Conditions
R12 Logical Operations Between Numbers and Conditions
R13 Applications of Logical Operators
SECTIONS LISTS AND ARRAYS
51 Dimension
S2 Index Variable
S3 Lists
54 Examples of Lists
S9 String Arrays
S6 Two Dimensional Numeric Arrays
57 Multi dimensional Arrays
S8 | Useof Arrays
SECTION T SORTING, SEARCHING AND STORING ARRAYS
T1 Searching and Sorting
T2 Bubble Sort with Flag
T3 Alphabetic Sort
T4 Insertion Sort
T5 ShellSort
T6 Quick Sort
T7 Index Sort
T8 Linear Search
T9 Binary Search
T1Q Storing a List
T11 Storing a String Array
T12 Storing Data in Strings
SECTION U THE COMPUTER MEMORY
U1 Memory Organisation
U2 PEEK and POKE
ОЗ System Variables
PART FOUR
APPLICATIONS PROGRAMS AND GAMES
SECTION V APPLICATIONS PROGRAMS
V] Programming for Applications
V2 Instructions and Input Checks
V3 Example Programs
V4 Games Programming
xi
351
270
271
272
279
279
279
280
280
283
284
286
287
292
292
294
295
296
299
302
306
309
310
312
314
316
319
319
325
332
353
299
354
359
425
V5 Example Programs 426
PART FIVE
COVERING THE WHOLE SPECTRUM 437
SECTIONW THESPECTRUM 439
W1 The Spectrum System and Keyboard 439
W2 Additional Spectrum BASIC Functions 456
W3 Graphics, Colour and Sound 466
APPENDICES 477
I Sinclair BASIC Summary 477
II Error Codes 483
HI ZX81 Character Codes by Keyboard Arrangement 487
ГУ Use of Cassette Tapes 491
V System Variables 493
VI Program Library 499
хи
INTRODUCTION
The central conviction behind this book is that programming
computers to solve problems is essentially a language independent
activity. This means that there is no reason why Sinclair BASIC should
not be learnt in exactly the same way as other high level languages: that
is, with the fundamentals of problem solving апа structured
programming introduced at an early stage. For the majority of readers,
Sinclair BASIC will be their first introduction to computing. We would
like to think that many will use it as a stepping stone to more advanced
study and application. Good problem solving and programming habits
will make both applications programming in BASIC and learning a
different structured language like PASCAL (which has a richer
programming environment than BASIC), much easier. We are
convinced that bad programming habits acquired early on are
extremely difficult to throw off; thus, this book has been designed to
introduce readers to the elements of computer programming in a
systematic manner, with the emphasis on correct rather than merely
adequate techniques.
Although we intend the text to be a serious treatment of Sinclair
BASIC, ав an introduction to computing it assumes по prior
knowledge of computers and only a minimal understanding of
mathematics. (Without the maths you will still be able to make your
way through the book, but if you don’t know what SIN and COS are,
you won’t be able to write programs using them!) Before all else, we
intend to give readers a full introduction to the essential control and
modular structures present in truly structured computer languages and
the way in which they operate in Sinclair BASIC. Once again, we hope
that with this behind them, readers will be able to go on to tackle more
sophisticated computer languages with a clear understanding of the
essentials of good programming in any language. This approach also
ensures that the reader who stays with his Sinclair machine will be able
to maximise its potential. As it runs on the world’s most popular
microcomputers, there can be little doubt that Sinclair BASIC will
become one of the most commonly used computer languages. This,
coupled with the fact that more and more software is becoming
available for the machines, makes it all the more important that users
attain a sound understanding of the language. Most published
programs in books and magazines have little in the way of
documentation. Debugging them, normally a tedious and difficult
task, becomes much easier if the techniques to do so are known.
This book introduces readers to three main sets of computer rules:
1 The rules of using your computer system.
2 The rules of the Sinclair BASIC programming language.
3 The rules of problem solving and structured programming using
Sinclair BASIC.
xiii
WHY DID WE WRITE THIS BOOK?
The sheer availability of the Sinclair machines demands that they be
treated seriously as a means of teaching progamming methods to a
large number of people. The programmer of a personal computer must
understand the characteristics of the machine, the high level language
(in this case BASIC), by which it is used and controlled and the
problem solving techniques to which it should be applied.
The first rush of books on the Sinclair machines has been, to put it
kindly, disappointing. Certainly none can be considered a serious text
on Sinclair BASIC. We felt that a book was needed which gave the first
time user a worthwhile home tutor on computing. So we decided to
write one!
WHO IS THE BOOK FOR?
The book has been written for the home user or school user who has
just bought a ZX81 or Spectrum and wants to learn how to program it
from scratch. Experience has shown that most Sinclair users will buy
more than one book on the subject of programming their machine.
This book will clear up a few misunderstandings and confusions
presented by other texts and will take you further into programming
techniques.
The text has also been designed as an aid to Sinclair BASIC
programmers who are having trouble designing error free programs
and are attempting some serious application.
HOW IS THE BOOK STRUCTURED?
As a self-study text, this book should be worked through with your
computer in front of you, so that programs and examples can be keyed
in as and when they arise.
The book has twenty-three Sections and is divided into five Parts.
Part 1: FIRST STEPS in which, after a brief introduction to the
machine and system (the first two units are ZX81 specific, and
Spectrum users should go immediately to the Spectrum specific
units - W1 on page 439 - before returning to start the main text at
Section C) you are told how to set it up correctly and start to write and
run simple BASIC programs.
Part 2: FUNDAMENTALS OF BASIC PROGRAMMING, which
first introduces the reader to the fundamentals of problem solving and
structured programming in BASIC. Тһе properties and
implementation of important language CONTROL
STRUCTURES - decisions, loops, and subroutines - are introduced,
together with the use of arithmetic, functions, strings, and how to print
and plot information on the screen.
Part 3: ADVANCED BASIC PROGRAMMING contains further
sections on programming methodology, as well as details of debugging,
XIV
testing and documenting programs. Interactive graphics is introduced,
together with the use of logical operators. Lists and arrays and methods
to sort and search them (vital subjects for applications programming)
and a treatment of how the computer uses its memory are fully
covered.
Part 4: APPLICATIONS PROGRAMMING AND GAMES
focuses the fundamental programming skills acquired in the earlier
parts of the book in the study of specific examples, linked to some
further discussion of programming technique.
Part 5: COVERING THE WHOLE SPECTRUM is the portion of
the book dedicated to the Spectrum. The first Unit of this Section,
dealing with the Spectrum system and keyboard, replaces the ZX81
specific Sections A and B, since there are major differences in the
arrangements of the two machines which require separate treatment.
The two following Units in this Part of the book deal with additional
features of the Spectrum not covered in the main text. It is intended
that, after using the first Unit to acquaint him or herself with the
Spectrum, the reader should defer reading these Units until the main
body of the text has been worked through. For the Spectrum user, this
starts at Section C.
The book is detailed and thorough. Remember that programming is
learned most effectively through experience. You should work through
the text systematically using your computer. Key in each example in
the text and run it. Some further programs to key in are available in
Appendix VI.
The exercises which appear at regular intervals throughout the book
are meant to give you practice in programming methods and to further
illustrate the function and application of the Sinclair BASIC language
constructions. Attempt most of them, but don’t ever allow yourself to
become discouraged. If you get stuck, go back through the relevant
section again.
We hope that you find learning BASIC programming with this book
a successful, enjoyable and useful experience, and that the knowledge
and programming skills obtained will be a step on the path to a more
advanced use of your Spectrum or ZX81 for real applications and
enjoyment.
XV
ІҢ
$E
ІН
H
dand pd
ІН
pur tips SMS, AN Cree
iwi S4 Шаға Mad өш do^ > eet 7 bonua «canted
‘Hee Kets?
volut. йй ay aint arrests ПОЛО grieved bets) tao tari ed gn
deabus nord бы? чый oe sura age Tiber: iron «М. заз (eo m £
-GA < ihe и ж ула % «©.» {кулан Ya кзжсжттер bgr
там, ъз + Min Pí Г ұлығ | nus зыр“ iai паз 1 D нұйуі,
АТИ
PART ONE
FIRST STEPS
Important Note: The first two units of this part are
specific to the ZX81. Spectrum users should ignore these
pages and directly GOTO the first Spectrum specific
section (W1 on page 439) before returning to the main
text (Section C on page 19).
Зин ERAS
LI
рч
SECTION A: ZX81 MICROCOMPUTER SYSTEM
A1: ZX81 Description
We assume you have in front of you the components of your ZX81
computer system.
It consists of:
1 Тһе ZX81 microcomputer with its touch-sensitive keyboard.
2 The Sinclair 16k RAM pack (Random Access Memory) or a
RAM pack of at least 16k produced by one of the other
manufacturers for the ZX81.
3 The ZX power supply, with a lead and plug, for connection to
the a.c. power supply, and the lead, ending in a jack-plug, to
connect the power supply unit to the ZX81.
4 The ZX printer and its connector socket.
A domestic UHF ТУ set to be used as a TV monitor.
6 А mono cassette recorder, with power supply lead if not battery
powered.
The aerial cable which connects the ZX81 to the TV monitor.
8 A pair of cassette recorder leads fitted with 3.5mm jack-plugs оп
each end.
сл
I
These components make up a complete system. As far as this text is
concerned, the least crucial component is the printer. Without it you
can simply ignore the printer-related portions, and will be able to work
through the book and learn the BASIC programming techniques just
as well. However, it is extremely useful to have a printer both for hard-
copy printouts of results, and more importantly for program listings for
documentation purposes.
There are a large number of ‘add-ons’ and accessories available for
the ZX81. None of these are of any interest as far as this book is
concerned, and most should be considered only when you have
absorbed the text and are going to write programs for specific purposes,
which might require the facilities provided by some of these units. A
noteworthy exception is a workstation to hold the components of the
system securely. There are types available which have on/off switches
for the d.c. power supply from the power supply unit, which saves a lot
of plug pulling and re-insertion, since pulling the power plug out of the
ZX81 is the only way to re-set the computer if it ‘crashes’ (i.e. will not
respond to keyboard commands).
What ¿s vital is enough memory. RAM memory is measured by
kilobytes (‘k’). The basic ZX81 has only 1k of RAM built in (2k on the
Timex/Sinclair 1000), and, without an add-on, RAM memory has
very little space available for programs. Computers are essentially
devices which store and manipulate data, and since programs, data,
and the manipulations all take up memory space, an add-on RAM
1
Figure 1
ZX81 SYSTEM DIAGRAM
ас. household power supply
AERIAL
TV MONITOR SOCKET
POWER
EAR а CASSETTE SUPPLY
МІС | RECORDER
NOTE: U.S. USERS MAY HAVE ANTENNAE ON/OFF SWITCH FITTED IN AERIAL
LEAD, SHOWN AS DOTTED BOX IN DIAGRAM.
memory is needed. RAM memory of up to 48k is available for the
ZX81, but 16k is more than enough for our purposes. Independently
produced RAM packs are usually just as good as those produced by
Sinclair.
The cassette recorder should be mono, since stereo tape deck
recording heads can cause problems, even used on one channel only.
The cheaper recorders work somewhat better (due to the less
sophisticated audio circuits being better for handling the crude form of
the computer’s signals) than more expensive ones, but try to get one
with a tape counter, as finding programs without one can be
irritatingly time consuming. You should always use the same recorder,
as problems can be encountered when playing back tapes recorded on a
different machine. Battery-operated recorders actually avoid some
potential problems, but must always have good batteries, to keep tape
2
speed constant. The cheapest solution to this in the long term
(especially since if you're not sure about the state of the batteries you
have to put in new ones) is to buy nickel-cadmium batteries and a
charging unit. All recorders have automatic level controls for
recording, but some cause problems with their continual variation
around the correct level (‘hunting’). Get a model that has been shown
to be compatible with the Sinclair computers.
Having a TV for exclusive use with your computer system 1s a good
idea, to avoid having to unplug and move around elements of your
system (it also avoids arguments with non-computing members of the
family!).
Some problems can interfere with the operation of your computer
(leaving to one side things like spilling coffee on it or otherwise abusing
it!). The first is overheating. After the computer has been on for some
time, it may heat up to such an extent that it ‘whites out’ and wipes out
the program you have just finished, except for that last line. This is
very irritating, to say the least. Some ZX81s seem to suffer from this
more than others. If it is a persistent problem, it can be helped by
placing a fairly hefty chunk of metal on top of the case to radiate heat
away more effectively. It should be approximately 3 x 2 inches and 0.5
inch deep, have a flat surface to sit on the ZX81 case, and should be
placed on the case, above the keyboard, on the left-hand side of the
case.
lhe corollary to this problem is that you should SAVE a long
program being developed or keyed in at intervals, and/or take listings
from the printer, to avoid a total loss if you do get a white out. The
same problem can also be caused by two other factors, and this
procedure will protect against the worst results from these problems as
well. The first is that household power supplies are sometimes
interrupted, or occasionally have brief large voltage fluctuations.
Computers are sensitive to such things, and a crash may be caused.
Other than buying a stabiliser which will continue to supply power
during such an interruption (of very short duration, but computers
work fast!) we cannot protect against a.c. supply fluctuations, but
similar results can sometimes be caused by appliances connected to the
same local power circuit switching on and off, and this should be
investigated if the problem is frequent.
The other main source of problems is the connector to the RAM
pack and printer via the edge connectors at the back of the ZX81.
Movement can be caused in this connector by flexing the system whilst
keying in programs. This can be minimised by always pushing the
connectors home firmly before switching on, but a better solution is to
attach the components to a board, fixing them down to a suitably rigid
base with ‘Blu-Tack’ or the double sided adhesive pads that are now
available. Fix the printer down as well- the process of tearing off
printout can move printer and connector if you are not careful. Note
that the method of fixing cannot be permanent, which is why Blu- Tack
3
or a similar plastic fixative is recommended.
The edge connectors themselves are gold plated, but they connect to
the printed circuit board edges which may become oxidised, causing
circuit problems (not necessarily white-outs or crashes — the keyboard
may cease to work, or the printer miss lines, for example). Proprietary
(non-abrasive) contact cleaners should be used to ensure clean
contacts.
Other than the problems above, the only maintenance that should be
needed is the brushing away of the dust that accumulates in the printer
from the burnt-off particles of paper. After removing the paper holder,
use a soft small brush (e.g. a small paint brush) to clear away the dust.
Pay particular attention to the slot in which the electrode runs, but if,
as sometimes happens, the electrode is visible, do not disturb it. (The
electrode is a small piece of wire which is normally not visible, but if
BREAK has been used it can be left in the middle of the printer slot.)
A2: Function of Components
This is a programming text, not a manual on computer architecture or
computer science. However, we thought it might be useful to provide
you with a brief rundown of the functions of each of the components of
your microcomputer system.
Device Function
ZX81 computer board Data processing and control of
(inside case) information handling. Input
from keyboard or cassette.
Output to TV screen and
printer.
Keyboard Input of information. Programs,
data and commands are keyed
in. On-line control.
TV set Used as V.D.U. (visual display
unit) monitor. Provides on-line
output of information — visual
display of programs, results
(data, graphs, pictures) and
control commands.
Cassette recorder Off-line storage of information.
Program data are stored (written)
as coded electromagnetic
impulses on cassette tapes. They
can be played back (loaded) at
any time for use again. The
computer reads the data from
the tape.
ZX printer Output device, to provide a
permanent printed record of the
screen display, program listings
or information in the computer
memory. Prints on
electrosensitive paper.
16k RAM pack Add-on memory enabling large
Power
Cables
programs to be stored and run.
K stands for kilobyte. One byte is
eight 22/5, which аге the binary
digits (0 and 1, represented by
on-off switches in the computer)
computers work with. A kilobyte
is roughly 1000 bytes, hence the
name. (It is actually 29, 1024).
supply Supplies the d.c. current (9 volts
at 1.2 amps) to run the
computer, RAM pack and
printer, from the household
power supply.
To interconnect the devices
which make up the system. The
printer uses the same socket as
the memory pack and has an
extension socket to allow this.
The printed circuit board inside the ZX81 holds and connects the IC
(integrated circuit) microchips which provide the computing facilities.
These
1
are:
Z80A CPU (Central Processing Unit) microprocessor chip
which is the heart of the system. It is used in many other
microcomputers, and performs the arithmetic manipulations.
ROM (Read Only Memory) chip holds the 8k BASIC
interpreter which translates BASIC instructions into the
machine code instructions that the Z80A operates with. The
data in this chip is fixed, hence the name, and also stable — it
remains when the power is switched off.
3 RAM (Random Access Memory) chip provides a 1k* memory
store. When the memory pack is fitted it blocks off this memory
and substitutes its own 16k of memory. This memory is
volatile — the data is stored as electrical impulses and is lost When
the power is switched off. This memory stores the BASIC
programs, the values of variables (including some system variables
that the computer uses to organise its own affairs), a memory
picture of the ТУ screen display, and the stacks which hold the
numbers whilst they are being manipulated. This is covered in
more detail in Section U.
4 The Logic chip co-ordinates the operation of the other chips.
Also mounted on the board are: the stabiliser for the 5 volt supply the
computer takes from the power supply, the TV signal modulator and
the sockets for the connecting cables to the ГУ and cassette recorder.
*2k on the TS 1006.
SECTION B: GETTING TO KNOW THE ZX81
B1: Connecting Up
1
Lay out the ZX81 system devices on your work area as оп page
2. It is far better to have an area where the system can be set up
permanently. Failing this, a board can be used to mount the
components.
Place the a.c. power supply plugs of the power supply, ТУ and
tape recorder next to the sockets. A plug board with multiple
sockets mounted on it is better than an extension socket fitting.
Connect the printer socket into the 23 pin edge connector at the
back of the ZX81. Get the slot in the ZX81 board and the block
in the printer socket aligned and push in gently but firmly.
Connect the 16k RAM pack socket into the extension connector
at the back of the printer socket in the same way. This is better
done with the ZX81 flat on the table to avoid too much stress on
the connectors, which might occur if you are holding up the
LAB,
With both connectors inserted, push the RAM pack firmly in to
ensure the connectors are fully seated home.
Connect the power supply cable into the socket marked DC on
the left-hand side of the ZX81.
Connect one end of the twin jack-plug leads, placing one jack-
plug into each of the MIC and EAR sockets on the cassette
recorder.
Place the other jack-plugs into the ZX81 sockets. It is very
useful to have the EAR and MIC sockets marked on the top of
the ZX81 case, where the marks can be seen. Use sticky labels of
some type to mark which is which, and also the exact centre of
the plug socket. This will save much probing of sockets (there
are no guides to ensure you get the socket) and peering at the
markings on the side of the ZX81, which are scarcely visible
when the ZX81 is flat on a surface.
The yellow banded plugs should go to both MIC sockets. You
can also mark the other jack-plug with E or EAR as a helpful
aid. Push the jack-plugs gently in, making sure the tips are in the
sockets (which has to be done by feel) until a resistance is felt,
then push until they click into place. Waggle them slightly to
ensure they are well-seated.
Connect the aerial lead into the ТУ aerial socket at the rear of
the TV and into the TV socket on the ZX81. A slight twisting
motion may be needed if the fit is tight.
US Users will find that the TV connects to the antenna lead with
standard terminals, and an antenna ON/OFF switch is fitted between
the antenna lead and the antenna lead that plugs into the
7
Timex/Sinclair 1000 version of the ZX81. This switch must of course
be ON.
Straighten the interconnecting cables on your work area at this
point. Make sure that the cassette leads are not in contact with
any a.c. power leads.
SWITCHING ON
оомо C
10
11
12
13
Ensure that the TV receiver is off and that no cassette recorder
keys are depressed.
Plug the power supply, TV, and cassette recorder plugs into the
a.c. power supply.
Switch on the a.c. power sockets (if they have switches).
There are no ON/OFF switches on the ZX81 or on most cassette
recorders - they are now powered up.
Switch on the TV.
Turn the volume control on the ТУ to zero.
Turn the brightness control to MAXIMUM.
Turn the contrast control to MINIMUM.
Tune in the TV. With a rotary tuning control, turn to channel
36. Otherwise select a channel, using the pushbutton or other
channel select switch, and tune this channel in. When the ГУ is
at the right setting, a small black square with a white K inset
appears. This is the K-cursor, and appears on the bottom left-
hand side of the screen.
U.S. Users should note that the Timex/Sinclair 1000 version of the
ZX81 has a channel select switch for Channel 1 or Channel 2 fitted
underneath the case. Choose whichever channel is not transmitting in
your area, and select this channel on the TV and the computer.
Adjust the tuning, brightness and contrast until the cursor is
distinct, and the white K clear.
Check that the cassette recorder keys function. Insert a blank
cassette, and try all the controls.
Insert a roll of silver printing paper into the printer and press the
button on the right-hand side of the printer to feed some paper
through. Check the paper does not rub on either side of the
printer as it comes through.
Press the key and then the [NEWLINE (ENTER) | key.
The printer will start to copy what is on the screen. About 3
inches of paper will be fed through. There will be nothing
printed on it as there is nothing on the screen. A message 0/0
will appear at the bottom of the screen.
N.B. The bottom two lines of the screen are never printed
and are used for keying in program lines and commands. These
program lines, when correct, are transferred into an area of
8
memory reserved for the programs by pressing the NEWLINE
(ENTER) key. The program lines will then appear on the
printer when the COPY command is given.
14 Press characters at random on the keyboard. They will appear at
the bottom of the screen. Press and [EDIT | keys
together to clear the screen.
15 If the cursor will not appear on the screen switch off the
power supply and adjust the 16k RAM pack and printer
connections. Switch on the power supply again and retune the
TV.
N.B. Never adjust or pull out the RAM pack when the power
supply is ON, you may damage it.
16 Other components failing to work will probably be caused by
plugs not switched on, or fuses blown. Alternatively, it could be
that some connections are not being properly made. You should
remove and re-insert Jack-plugs and connectors.
17 On leaving your computer:
a Leave it connected up
b Switch OFF a.c. power supply plugs and TV
c Disconnect plugs from sockets.
B2: The Keyboard
The ZX81 keyboard has 40 touch sensitive keys arranged in 4
rows of 10 keys.
At first sight it looks like a typewriter keyboard, but a closer look
reveals that some keys have five functions or characters written on
them. In fact:
Six different characters can be obtained from some keys!
The keyboard contains:
(1) The digits 0 to 9
(2) The letters of the alphabet printed in upper case
(3) The complete BASIC language
— instructions
— commands
— arithmetic, conditional and logical operators
— arithmetic functions
(4) Grammatical signs and symbols
(5) Special control keys
(6) Graphics symbols
These are all called characters.
Notice that words like PRINT, RUN, SLOW, LET, INKEY$ are
9
written on the keys and are printed on the screen when we press that key
in the correct mode.
The facility of complete words in the BASIC language being printed
at the press of a single key is called
SINGLE KEYSTROKE BASIC
On most other computers you have to key in each letter of, for
example, the instruction PRINT. This is inefficient. The ZX81 is very
powerful in this respect.
The keyboard contains most of the characters in the ZX81 character
set and a few special keys. Some 202 different characters are available.
Some print on the screen, others are non-printing, e.g. RUBOUT
(DELETE).
Each of the different types of character 1s described in Section B4.
The ZX81 keyboard layout is reproduced in the diagram on the next
page.
B3: Cursors
is] [>]
Cursors indicate what operational mode the computer is in and what
symbol or name should be typed in next. They appear in inverse video
(a white letter in a black square).
Keyword mode.
ZX81 expects a command
a line number
or a keyword
Keywords are the symbols printed on the keyboard
above the keys (see keyboard). SHIFTed keys also
function in this mode.
Letter mode.
Occurs at most other times.
ZX81 expectsa letter
a number
an operator
ora special command
SHIFTed keys function in this mode.
Function mode.
Obtained by pressing FUNCTION key (SHIFT,
NEWLINE/ENTER).
The functions obtainable are printed under each key
in white.
10
Figure 2
ZX81 KEYBOARD
ГЫ 86791 s e Se a e
M
CODE PEEK
IT
ap ж
JE es DS Mei ш ч"
AG БЕЙ K [ENTER]
ARCSIN = Ж: DS
COPY CLEAR fis
Only one function can be obtained each time
FUNCTION is pressed.
Graphics mode.
Obtained by pressing GRAPHICS key (SHIFT, 9).
Mode lasts until the GRAPHICS key is pressed again.
In the graphics mode 36 different characters are
obtained by pressing the keys with the SHIFT key
depressed as well. These are shifted graphics characters.
38 different characters (mainly letters printed in the
inverse mode) are obtained by pressing the keys.
[s | Syntax error cursor.
This cursor appears in a statement line at the bottom of
the screen if the computer finds that there is an error in
it. It appears when we try to enter an incorrect line of
program into memory (i.e. after we press NEWLINE
(ENTER) when at the bottom of the screen).
The [S | cursor appears next to the last error in the
line. (There can be more than one). Editing on the line
сап take place immediately. The [5 | cursor disappears
when an edit operation is performed. It will re-appear
(if necessary) when NEWLINE (ENTER) is pressed
again.
Current line cursor.
When entering statements into the program the last line
to be entered is called the current line and is indicated
by this symbol placed after the line number. The
movement of this cursor up and down the screen,
pointing to different lines, is controlled by the { and
^ keys (SHIFT 6 and 7).
If EDIT (SHIFT 1) is pressed, the current line is
brought down to the bottom of the screen and can be
edited.
B4: The Different Character Types
THE 6 CHARACTER TYPES ON A KEY
If we examine a particular key, say [R ] , we can classify the 6 character
types, as seen in the diagram below.
RUN
LETTER
<=
ec
=
INVERSE GRAPHICS
GRAPHIC
INT -
KEYWORD
On top of the R key is the word RUN. This is a KEYWORD
character.
All characters printed on the keyboard in this position are
KEYWORDS. KEYWORDS will be printed on the screen if the
desired key is pressed when the ZX81 is in KEYWORD MODE (1.е.
the cursor is on the screen).
Exercise
If the | К | cursor is at the bottom left-hand side of the screen then enter
a keyword. Press the | PRINT | (P) key. Notice that PRINT appears on
the screen but the cursor has changed to an cursor and the
computer is in the letter mode. This means that it 1s expecting a letter
to be keyed in next, e.g. A.
If we try to key in another keyword, e.g. , the keyword
PLOT does not appear. Instead the letter O is printed. So the rule is:
No two keywords may be entered in succession.
To clear the screen and return to mode press
keys together. Try it. Print different keywords on the screen. Which
one does not print?
LETTER
The LETTER characters (or OWERTY characters as they are
sometimes called) are the bold type letters on each key. They are
identical to those on a typewriter keyboard. It is worth trying to
memorise these. Do it by lines, and in groups of five.
Letter characters may be keyed in when the computer is in the letter
mode and the cursor appears in the entered program line, or at the
bottom left-hand side of the screen. Certain letters may be entered in
the mode as default when there is no keyword on that key, e.g. the
digits 0-9 and the full stop[ e] [BREAK] is also an exception. A space
Is printed in the mode.
13
Exercise
Key in | PRINT | to obtain the mode. Then key in the letters,
starting from [1].
What happens with | NEWLINE (ENTER)| and |SPACE |?
SHIFT
There are 39 SHIFT characters on the keyboard. These may be
obtained in the Or modes, 1.e. when Or is on the
screen.
To obtain these characters or symbols e.g. in our diagram,
press the | SHIFT | key and the desired | CHARACTER | key at the
same time.
Exercise
Start keying in the SHIFT characters starting with on the top
line of the keyboard.
Notice what happens with:
EDIT
THE ARROW KEYS (^4 | e>)
GRAPHICS
RUBOUT (DELETE)
FUNCTION
GRAPHICS
There are two types of graphics characters, the characters like Bll as in
our diagram below, and the letter and shift characters printed in
INVERSE (i.e. white letter on black background) on the screen ( Ia).
Exercise
To print the graphics characters on the screen key in:
14
Keys to Press What happens on the Screen
PRINT
E] PRINT
PRINT
ГЕ | PRINT
[К | PRINT
PRINT
[Эй] PRINT
NEWLINE (ENTER) ББЗ at top of screen
0/0 at bottom of screen
NEWLINE (ENTER) [3 (clears screen)
Notice the mode cursor changes.
Note that to come out of the mode, you need to press
again, to get the cursor back. To clear the screen
press |
Repeat the exercise and obtain all the graphics characters. Where no
graphics character is printed on the key then the inverse of the shift
character is obtained by default. ‘Test this out.
INVERSE GRAPHICS
These characters are the inverse video letter characters, and are
obtained in the GRAPHICS mode, i.e. cursor on the screen, when
the desired key is pressed.
Exercise
Key in the characters as before, but this time only press the letters and
not the shift characters when in the mode.
What happens when you press |SPACE] ?
FUNCTION
There are 24 Function characters that are obtained only in the
Function mode, when the [F ] cursor is on the screen. The ГЕ |cursor is
obtained by pressing the |SHIFT | and | FUNCTION | keys together.
Only one Function character may be entered. The mode changes to
after entry. To input another Function character we need to get
back to the mode again.
Exercise
Get into the FUNCTION mode and key in all the function characters.
Key in -
Lr]
What happens? Press NEWLINE (ENTER) again to clear the screen.
HOW TO OBTAIN THE DIFFERENT CHARACTER TYPES
Character Number of To Obtain | To Obtain the
Type Chars. the Mode: | Character:
mmm f 26 | [E] | лонае
SHIFT 39 [K ] Automatic SHIFT
CHARACTER
LETTER 39
Automatic CHARACTER
K]
(sometimes)
mt = =
GRAPHICS CHARACTER
INVERSE
GRAPHICS
Е
GRAPHICS
CHARACTER
SHIFT
FUNCTION
CHARACTER
Exercise
Using the above table, obtain all the modes and key in example
character types.
ALPHABETIC CHARACTER/KEY TABLE
The following table locates the letter or number key which provides
each character (keyword, function, or symbol) on the keyboard. Use
this table when entering programs until you are familiar with the
placing of all the commands. An * indicates a non-printing character.
BASIC Word Keyword (K), Function
or Shift and Key to Press
ABS Function G LPRINT Shift S
ACS Function S NEW (K) A
AND Shift 2 NEXT Shift N
ASN Function A NOT Function N
AT Function C OR Shift W
ATN Function D PAUSE Shift M
CHR$ Function U PEEK Function O
CLEAR (K) X PI (m) Function M
CLS (K) V PLOT Function О
CODE Function I POKE Function O
CONT (K) C PRINT Function P
COPY (K) Z RAND Function T
COS Function W REM Function E
DELETE Shift Ø * RETURN Function Y
DIM (K) D RND Function T
EDIT Shift 1 * RUBOUT Shift @ *
EXP Function X RUN Shift R
FAST Shift F SAVE Shift S
FOR (K) F SCROLL Shift B
FUNCTION Shift NEWLINE(ENTER) SGN Function F
GOSUB (K) H SIN Function Q
GOTO (K) G SLOW Shift D
GRAPHICS Shift 9 * SOR Function H
IF (K) U STEP Shift E
INKEY$ Function B STOP Shift A
INPUT (K) I STR$ Function Y
INT Function F TAB Function P
LEN Function K TAN Function E
LET (K) L THEN Shift 2
LIST (K) K TO Shift 4
LLIST Shift G UNPLOT Function W
LN Function Z USR Function L
LOAD (K) J VAL Function J
17
SYMBOLS
Symbol Cursor and Key Symbol Meaning
K or L, Full stop or dec-
imal point (Separate key)
š K or L, shifted Full stop. Comma
; K or L, shifted X. Semicolon
z К or L, shifted 2. Colon
? К or L, shifted C. Question mark
`y K or L, shifted P. String quote
iis K or L, shifted О. Quote image
( K or L, shifted I. Open bracket
) K or L, shifted O. Close bracket
£ K or L, shifted SPACE. Pound
$ K or L, shifted U. Dollar
+ K or L, shifted K. Plus
- K or L, shifted J. Minus
7 K ог L, shifted В. Times
/ K or L, shifted V. Divide
те K or L, shifted Н. To power
= K or L, shifted L. Equals
> K or L, shifted M. Greater than
< K or L, shifted N. Less than
© = К or L, shifted К. Less than or equal to
> = K or L, shifted Y. Greater than or equal to
<> K or L, shifted T. Not equal to
“= K or L, shifted 5. Cursor left
{ К ог L, shifted 6. Cursor down
T K or L, shifted 7. Cursor up
Т” K or L, shifted 8. Cursor right
18
SECTION C: BASIC BASIC
C1: The BASIC Language
This book is all about BASIC, which is the world's most commonly
used computer language. Just as English is a natural language used to
communicate with people, BASIC is a formal language used to
communicate with COMPUTERS. Like natural languages BASIC
has grammatical rules which, although they are fairly simple, must be
strictly followed to ensure that the computer understands exactly what
it is being instructed to do.
BASIC stands for Beginners All-Purpose Symbolic Instruction
Code. It was invented in 1964 in the USA and is a combination of
simple English and algebra. BASIC is the language we will use
throughout this book to write PROGRAMS. Programs instruct the
computer what to do, and the sequence in which particular operations
are to be performed.
BASIC is a high-level programming language. The instructions we write
in BASIC are interpreted by a built-in program into the low-level
programming language (the MACHINE CODE) that directly controls
the switching of the electrical impulses inside the MICROCHIPS
which store and manipulate the data. High-level languages like BASIC
are far easier to write programs in than the low-level languages, and
the simple language and structure of BASIC was designed to be easy to
learn. The Sinclair version of BASIC also has single-keystroke entry of
BASIC words, which makes mistakes in spelling impossible.
C2: A Simple Program
A sequence of BASIC statements is called a PROGRAM. Here
is an example of a program:
10 INPUT A
20 INPUT B
30 LETS=A+B
40 PRINT S
The simple program above adds two numbers keyed in on the
keyboard and prints the results on the screen. A program is keyed (or
typed or input or entered) into the computer by you, the programmer,
line by line, from the keyboard.
Before we key a program in we design it to make the computer do
exactly what we want. We first write a program down line by line on a
piece of paper. This is called CODING.
After coding the program we key it into the computer and RUN it.
To RUN it we give the computer a COMMAND to RUN the program
to see if it works. It probably won't work the first time, unless it's as
19
simple as our example. A program which doesn’t work as intended is
said to contain ERRORS or BUGS.
If we have asked it to do something it can’t do, or forgotten to
include an instruction the computer will tell us what is wrong and give
us an ERROR MESSAGE. If the program runs without error
messages but doesn’t do what we wanted it to then it is the
programmers’ fault. In either case we need to correct or EDIT or
DEBUG the program. We do this whilst the program is in the
computer, using the editing facilities of the computer.
Editing or revising a program is called PROGRAM
DEVELOPMENT. When the editing is finished and the program
works we take a LISTING of the program on the PRINTER. We can
also SAVE a copy of our program on cassette tape and STORE it so
that we can LOAD it back into the computer.
The complete exercise of designing, coding, developing and
documenting a program is called PROGRAMMING.
C3: A Statement
This is a BASIC statement:
10 INPUT A
A statement is also called a LINE. A statement can:
(1) instruct the computer to do something
(2) state something
A statement is composed of: a line number, e.g. 10
an instruction, e.g. INPUT
some variables, e.g. A
Statements are either: Executable — those which specify a program
action, as with our INPUT A, or Non-Executable — those which
provide information for the user of the program.
All variables (e.g. A in our example) must be initialised to a start
value before being used in a program. In this case the statement:
10 INPUTA
tells the computer to request the user to input a value for the variable A
from the keyboard.
C4: Statement Numbers
Each BASIC statement or line must begin with a statement
number, as with 20 in this example.
20 INPUT B
The number 20 is called a statement number or line number. The
statement number is chosen by you, the programmer. It may be any
number from 1 to 9999 inclusive. ‘The computer uses the numbers to
keep the statements in order. Each statement has a unique statement
20
number. If you use the same statement number twice, the second line
will replace the first.
Statements may be keyed in via the keyboard in any order. The
computer sorts them into the correct sequence. Statements are usually
numbered in tens so that additional statements are easily inserted later.
For example:
10 INPUT А
20 INPUT B
25 INPUT C (Inserted line)
30 LET S=A+B
The computer runs the program in order of statement numbers.
C5: Instructions
A statement gives an instruction to the computer. In this
example it is LET.
30 LETS=A+B
Instructions are called statement types because they identify a type of
statement. In our example the statement is a LET statement. It tells
the computer to let the variable S have a value equal to the sum of the
values of variable A and variable B.
C6: Numeric Variables
A numeric variable is the name given to a storage location
which holds a number in the computer's memory.
A numeric variable can have a name which is:
A letter from A-Z
or A letter followed by a number
or A group of letters and numbers
Variable names must start with a letter.
Examples of numeric variables: A
NUMBER 1
Numeric variables are used to represent numbers inside the computer.
We can give (or assign) different values to a variable. The numbers we
give to variables are used in calculations.
Variables are symbols or names given to parameters or quantities.
They represent the VALUE of the parameter, i.e. the number stored
21
in the named memory location. We can use variable names which
remind us of the parameter concerned, but they should not be too long
or you will find them tiresome to key in (which is why single letters are
usually used).
For example, we could use:
S — Speed
PRICE - Price of fish
SUM 1 - Sum of the first set of numbers
R3 - Resistor Three
In our program the statement
10 INPUT A
sets up a variable in the computer's memory with the symbolic name
A. We could have called it NUM1, or even FIRSTNUMBER.
The statement tells the computer to ask us to input a value for À
when we run the program. If we key in the number 3 the memory cell
allocated to A will contain the number 3. This value is then used in all
calculations involving À until we change its value.
In the statement:
30 LETS=A+B
S, A and B are the variables in the algebraic equation S= A + B. Š is
our ‘unknown’ and will take the sum of the values of A and B. The
computer will work out the value of A + B and put the result in the
memory cell it has allocated to the variable S. The computer will not let
us input LET A+ B = S (it will give us a syntax error), because the
variable to be given a value must come first. A + B is not a valid
variable name.
Variables are so-called because their values can vary or change,
according to the values we input, or in the course of a program, when
we instruct the computer to do something which causes the value to
change. For CONSTANTS, which are quantities which do not change
their value, we set up a variable in the same way, by giving it a name
and a value with a LET statement and let it keep the same value — a
variable that doesn't vary!
Variable names may be of any length, but they must start with a
letter, and must only contain the alphanumeric characters (the letters A
to Z and the numbers @ to 9). They can have spaces included, but this
is unwise, as it is easy to key іп PRICEI, for example, when you
initialised a variable as PRICE 1. The computer will consider them to
be two different variables. The inverse video (white on black)
characters also cannot be used in variable names.
22
C7: Strings and String Variables
STRING
A STRING is a group of characters enclosed by quotation
marks.
The following are examples of strings:
“PETER”
“12345”
“JANUARY 1ST, 1982”
sot “Жы А,
“REF:A2”
As well as numbers, computers can also handle text or groups of
characters. Го define a group of characters as a string, we have to place
quotation marks at the beginning and end. This tells the computer, for
example, that the string ‘“TOTAL’’ means the characters T,O,T,A,L,
and not the numeric variable TOTAL, which is a number.
Strings can contain any character which prints on the screen, plus
spaces, but a string cannot contain quotation marks, because the
computer thinks it has got to the end of the string when it gets to the
second quotation mark.
Now that you know what a string is, we can tell you that strings can
be handled by string variables, just as numbers can be manipulated
with numeric variables.
STRING VARIABLE
A string variable is used to store strings. It consists of a single
letter (A to Z) followed by the $ sign. For example:
A$, Z$, M$
We allocate (or assign) strings to string variables with LET statements,
as with numeric variables. For example:
10 LET A$=‘‘STRING 1"
20 PRINT A$
The memory store allocated to A$ will contain the string ‘STRING 1’
(line 10).
When we RUN the program the computer will print the contents of
memory store A$ on the screen (line 20), i.e. STRING 1. Note the
string is printed without the quotation marks. The string is just the
characters inside the quotes.
22
C8: Operators and Operands
OPERATORS
Operators perform arithmetic, logical or conditional
operations on variables or numbers.
In our program the line:
39 LETS=A+B
uses the two arithmetic operators
= and +
OPERANDS
Operands are the variables or numbers which are
manipulated (i.e. operated on) by the operators.
In the line:
30 LET S=A+B
the variables S, A and B are operands.
C9: Format of Statements
BASIC is a ‘free format’ language. The computer will ignore
extra blank spaces in a statement.
The following statements are equivalent:
10 INPUT A
10 INPUT A
10 INPUT A
The computer will automatically leave spaces after each line number
and a space after keywords. It will list programs with all the other
spaces you include between instructions and variables. It will ignore
them when you run the program.
C10: Keying in a Statement
Statement to be keyed in:
10 INPUTA Press
If your computer system is set up and ready for use (see Section B1) the
cursor will be in the bottom left-hand corner of the screen. You can
now key in the first statement.
24
Character or Cursor Keys to What appears
instruction Press on the Screen
to key in
[к]
2 2 19 [к]
ж
INPUT I 19 INPUT
A [z]. A i mera [Z]
*
NEWLINE
(ENTER)
Entered line is
transferred to top
of screen
*
on Spectrum in CAPS mode
PRESS NEWLINE (ENTER) AFTER EACH STATEMENT
The |NEWLINE (ENTER)| key must be pressed after each
statement has been entered.
10 INPUT A
20 INPUT В
30 LET S =A+B[NEWLINE (ENTER) |
40 PRINTS
Pressing the | NEWLINE (ENTER) | key informs the computer that the
statement is complete. The computer checks the line for mistakes then
transfers the statement to the top of the screen and returns the
cursor to the left-hand side of the screen, ready for us to enter the next
program line.
Notice that the line at the top of the screen now contains the
CURRENT LINE CURSOR:
This indicates the last program line entered and accepted by the
computer. It appears immediately after the line number:
10 [>] INPUT A
25
C11: Correcting Errors
RUBOUT (DELETE)
The RUBOUT (DELETE) key acts as a backspace, deleting
the character symbol or keyword immediately preceding (to
the left of) it.
As we type in a line we may press the wrong key. For example, we
might get:
10 INPUTS
where we pressed S instead of A. To correct this we press RUBOUT
(DELETE) and we get:
10 INPUT
We may now continue and type in A.
The horizontal arrow keys move the cursor one character or
keyword to the left or right along a line as indicated.
For obvious reasons, these keys are also referred to as cursor control
keys.
To correct an earlier mistake on a line
(a) Use the arrow keys to move the cursor to a position immediately
to the right of the character to be changed.
(b) Press RUBOUT (DELETE) to delete the incorrect character,
and key in the correct character.
(c) Use the arrow key to return the cursor to the end of the line, if
you have more to key in. Otherwise, you may press NEWLINE
(ENTER) immediately. It does not matter if the cursor is In
the middle of the line.
To delete a complete line
This can be done by using the > key to get the cursor to the end of the
line, if you are not there already, and then using RUBOUT
DELETE) repeatedly until the line is completely deleted and just the
cursor remains. This is tedious on a ZX81, without the
Spectrum’s repeat key, especially on a long line. A better way is:
(1) Press EDIT
(2) Press NEWLINE (ENTER)
26
If you are keying in the first line of a program and there are no existing
lines at the top of the screen, pressing EDIT will clear the line.
If there are program lines at the top of the screen, pressing EDIT
clears we current line and brings down the program line marked with
the cursor. Pressing NEWLINE (ENTER) sends this line up
again г. clears (һе current line.
Exercises
1 Start keying in the first line of the program. Don’t press
NEWLINE (ENTER).
Play around with the cursor control keys and RUBOUT
(DELETE).
Delete the complete line.
3 Key in the first line and press NEWLINE (ENTER).
Key in the second line.
4 Delete the second line using EDIT and NEWLINE (ENTER).
5 Кеуіп the second line. Key in the third line to read:
30 LET X =A + B. Press NEWLINE (ENTER)
Use EDIT to bring this line down again. Use the cursor control
keys to put the cursor to the right of X and delete it. Insert S.
Leave the cursor where it is, and press NEWLINE (ENTER) to
send the line to the top of the screen.
6 Key in the complete program.
N
C12: Commands
COMMANDS are direct instructions to the computer. They
are executed immediately. They do not need line numbers, as
they are not part of a program.
Commands give us direct control over the computer.
Examples are:
RUN
LIST
BREAK
SAVE
To execute a command, we key it in. If it is a command that is printed,
it will appear on the bottom line of the screen. This area of the screen
must be empty. Then press [NEWLINE (ENTER). Some commands
are executed instantly, without pressing NEWLINE ie i (e.g.
BREAK), and are not printed on the screen.
Most commands are also used as instructions in programs. Some of
the commands that can be used as direct commands are not actually
very useful in this role. Equally, some that could be used in programs
never are. However, each command has a key role to play in the
27
BASIC language and we will deal with the individual commands as we
encounter them in the text.
You have already met the NEWLINE (ENTER), RUBOUT
(DELETE), < and -” commands, and the mode commands
(GRAPHICS and FUNCTION). Together with EDIT, RUBOUT
(DELETE) and BREAK, plus the f and $ arrow keys, these are the
commands that don’t print, and act instantly. All the others need
NEWLINE (ENTER) to be activated.
C13: Editing the Program
EDIT
The EDIT command copies the program line indicated by the
cursor at the top of the screen, to the bottom of the screen,
replacing any current line. The line brought down can then
be edited or changed.
EDIT may also be used for entering lines that are similar where only
the line number changes:
(1) Key in the line.
(2) Press NEWLINE (ENTER) - line goes to top of screen.
(3) Press EDIT - line copied to bottom of screen.
(4) Use RUBOUT (DELETE) to delete the line number.
(5) Key in new line number.
(6) Press NEWLINE (ENTER) - new line goes to top of screen.
The same procedure can also be useful with lines which only vary
slightly, i.e. perhaps only the line number and a variable are different.
If you can save keystrokes by bringing down a line and revising it, then
do so. The technique is as above, but after (5) you must use the cursor
control keys to shift the L-cursor along the line and use RUBOUT
(DELETE) to erase the variable (or keyword) that needs to be
changed. Insert the new character, and press NEWLINE (ENTER).
These commands move the cursor in the entered program
at the top of the screen from one line to another. This enables
us to then copy down any line in the program for editing using
[EDIT].
Deleting a line in the entered program
To delete a given program line which has been entered and is at the top
28
of the screen just type the line number and press NEWLINE
(ENTER).
For example:
10 |NEWLINE (ENTER
will delete line 10 in the program. You will see it disappear from the
screen.
C14: Listing a Program on the Screen
LIST
The program has been entered into memory. To produce a
listing on the screen of all lines accepted by the computer key
in:
LIST NEWLINE (ENTER
LIST is a command that prints on the screen. It appears on the bottom
of the screen, and is executed when NEWLINE (ENTER) is pressed.
LIST N
Will list a program starting from program line N.
For example, if we key in:
LIST 30 NEWLINE (ENTER
our program will be listed from line 30.
We key in LIST, then the line number we want the listing to start at. If
we have a program that is longer than will fit on the screen, we use the
LIST (line number) command to display successive screenfuls of the
program. If the bottom line on the first screen is 210, for example, we
would use LIST 220 to get the next set of program lines. Listing a
program on the Spectrum which is larger than a screenful produces a
SCROLL? prompt. Answering this with anything other than ‘N’ or
BREAK scrolls the listing up so that the next screenful of statements
can be seen.
C15: Running the Program
Our simple program has been keyed into the computer line by line and
entered into memory.
Let's see if it works. We give the computer the command RUN.
29
RUN
NEWLINE (ENTER
The RUN command starts execution of a program at the
lowest numbered statement.
Run is a command and is keyed in. It appears at the bottom of the
screen. It will not be executed until [NEWLINE (ENTER)] is pressed.
When we do this the program starts operating. The screen will go
blank and the L-cursor will appear at the bottom. (This will be a
C-cursor if you are using a Spectrum in CAPS (capital letter) mode,
using CAPS LOCK as we advised.) The computer is now running the
program and asking us to input a number for the variable A.
Key in the number and press [NEWLINE (ENTER)] . The
L-cursor appears again at the bottom of the screen. The computer
requests another number, to be assigned to the variable B. Key in the
number | 5 | and press .
Our result (the number 8) is printed at the top left of the screen.
Notice the message that appears on the bottom of the screen. We can
also run the program from a line other than the first program line:
RUN N
RUN (Line Number)
This command starts execution of the program from the
specified statement (line) number.
RUN 20
will start a program at line 20.
Note that when the RUN N command is used all statements before the
specified statement number (N) will be ignored and any variables
defined in these statements will be considered by the computer to be
undefined because it has not RUN the lines. The program will not
work and an error message will result. All values of variables are
wiped out by the RUN command.
We can RUN the program as many times as we wish:
Key in [| NEWLINE (ENTER) | again
If the program has been run once and the message is at the bottom of
the screen, to rerun the program key in RUN. This overwrites the
message and pressing NEWLINE (ENTER) starts the computer
operating the program. The L-cursor appears to prompt for an input
again (C-cursor for Spectrum in CAPS mode).
30
The screen is now blank. We can get the program listing back very
easily:
Press NEWLINE (ENTER)
After running the program, the program listing re-appears at the top of
the screen if the NEWLINE (ENTER) key is pressed. The program
can now be edited if necessary.
C16: Error Messages
Our computer tells us it has finished running the program by giving us
a message. On the ZX81 this will be:
0/40
at the bottom of the screen. The Spectrum gives an expanded version
of the message:
0 OK, 40:1
This tells us that no errors were found and the program finished at line
40 (the last line). The number after the colon can be ignored in most
Spectrum error messages, as it refers to multiple-statement lines. We
shall not use these in this text. There is one case where it is 2, as we
shall see later.
These special diagnostic messages appear at the bottom of the screen
every time a program is run. If the program does not work a message
appears with the form:
E/N
E is a number or a letter indicating the type of error that has caused the
program to stop, and N the line number where the program halted due
to the error. The Spectrum adds a message briefly stating the cause of
the error.
We look up the meaning of E in the list of Error Codes in Appendix
II. This helps us to correct or debug the program, since we know what
sort of problem has occurred and which program line it happened at.
Exercises
1 Run the program on page 19 a number of times keying in
different values for A and B.
2 Press NEWLINE (ENTER) to get the listing. Change line 30 to
read:
30 LETS-A-«C
31
Now RUN the program.
The error message 2/30 (on the ZX81) appears. On the
Spectrum we get 2: Variable not found 30;1. So we have a type
2 error and the program stopped at line 30. A type 2 error means
we have forgotten to define a variable. We are now using the
variable C instead of B, but we have not yet given C a value, and
the computer could not complete the operation of line 30 due to
insufficient information.
Insert a new line:
25 INPUT C
and run the program again. It now works.
Why did the program originally stop at line 30?
Why do we now have to key in 3 numbers to make it work?
3 Add an extra line at the beginning of the program. Key in:
5 PRINT “PROGRAM ADDS 2 NUMBERS"
RUN the program, starting from different lines by using:
RUN
RUN 10
RUN 15
Why do you think RUN 15 does not work?
4 Edit the program to obtain the original version.
C17: How the Program Works
Line 10 tells the computer that a number must be
input and given the name A, (i.e. assigned to the
variable A). ‘The computer reads the line and prints
an at the bottom of the screen,* reminding us
to input a number. The computer will wait until we
key in a number. The number is then stored in
memory cell A. The computer goes to the next line.
Line 20 tells the computer that another number,
to be assigned to the variable B, must be input.
appears at the bottom of the screen* and the
computer waits until we key in a second number,
which is stored in memory cell B. The computer
goes to the next line.
Line 30 tells the computer that a variable 5 18 to
be assigned the value of the sum of the variables A
and B. The numbers in cells A and B are added
10 INPUT A
20 INPUT B
30 LETS=A+B
*This will be a C-cursor if using a Spectrum with the CAPS LOCK facility used, as
Spectrum users must do throughout this text to get program listings which appear the
same as the ones in the text. Use the CAPS SHIFT and CAPS LOCK keys
simultaneously on switch-on, and remember that the C-cursor will appear instead of
the L-cursor. We will not mention this again.
32
and placed in cell S. The computer goes to the next
line.
Line 40 instructs the computer to output the 40 PRINT S
value of Š to the screen. The computer looks for the
next line.
The computer can find no more statements to
execute in the program and gives a message 0/40
on the screen telling us that the program finished
with zero errors at line 40. The Spectrum gives the
same message, in the form 0 OK, 40:1.
The computer now waits for more commands.
C18: Naming the Program
5 REM “NAME”
Programs are named in a REM statement. The program name
is enclosed in quotation marks. The program is usually named
in the first statement in the program.
We need to give our program a name in order to:
(1) Differentiate it from other programs
(2) Store it permanently on cassette tape (SAVE it)
(3) Put it back into the computer from cassette tape in order to run it
(LOAD it).
The program name can be any combination of characters and any
length on the ZX81. On the Spectrum, program names for use with the
SAVE and LOAD instructions must start with a letter, and can only
have 10 characters in the name.
It is sensible to keep the program name short and relevant to the type
of program, although some programmers name programs after
themselves:
“PETER 1”
“PETER 2" ete.
Programs which undertake various kinds of statistical analysis could be
named:
"STATS
“STATS2” etc,
Programs which perform calculations for experiments in the laboratory
could be named:
"OPTICS З”
“FRICTION”
“TITRATION” etc.
If spaces are used in program names, it is easy to misread them, or
forget that there should be a space. If the program name is not one
word, we can use an asterisk:
“FETTER?”
“FOCALLENGTH” etc. ((FOCAL*LEN"' for the Spectrum)
33
Program names and cassette tape codes should be recorded in a
DIRECTORY which enables us to access a PROGRAM LIBRARY
of programs stored on tape.
We need to name our program: List the program and add a line
which names the program. For example:
5 КЕМ “SUMPROG”
or S REM “PROGI”
could be used. We will call our program “АПОПОЕК”, so key in
5 REM “ADDER”
34
SECTION D: SAVING, LOADING AND LISTING
D1: Saving the Program on Cassette Tape
We need to save programs on to cassette tape (the off-line storage medium
the Sinclair computers use) because when the power supply is switched
off (or disrupted - variations in the mains supply can affect the
computer) the RAM memory and the registers in the CPU are cleared
and we lose the program. The memory is said to be volatile. This means
we have to key it in again — not too bad for a 5 line program, but a 50
liner will take you an hour!
If we had made a copy of the program on to magnetic cassette tape
using the SAVE command we could have reloaded it into the computer
quickly, using the LOAD command. Tape storage is not the quickest
or most reliable method used for off-line storage, but it works, and has
the advantage of low cost. The ZX81 reads and writes tape fairly slowly
in computer terms, and a large program will take some minutes to
LOAD or SAVE. The Spectrum loads programs several times faster.
Software (programs) stored on tape is available for use when needed,
making it PERMANENT.
Software also has to be PORTABLE. Programs we write can be
used by other people with the same computer, or software available on
cassette can be bought.
SAVE
SAVE “NAME”
The SAVE command outputs the program and variables to
the cassette recorder. If the cassette recorder is in record mode
then a copy of the program will be made on the tape.
Spectrum users please note that the program name for SAVEing must
be 10 letters or less. The name can be in either upper or lower case (or
a mixture) but exactly the same name must be used to LOAD. It is
safer to choose to use capitals only.
SAVING THE PROGRAM
1 Check that the cassette recorder is plugged in (or has
good batteries).
2 Ensure it is connected to the computer, with the MIC-
MIC sockets being connected. See the important
Spectrum note below.
35
мы GO
Set the TONE control on the cassette recorder to HIGH.
Set the volume control on the cassette recorder to 3/4 of
MAXIMUM.
Insert a new C12 computer cassette tape into the
recorder. Short cassettes are more convenient than long
ones for our purposes.
Run the tape through on FAST FORWARD and then
REWIND to ensure equal tension.
Set the tape counter to zero and run the tape forward five
revolutions (about 20 or 30 seconds).
List the program on the screen and printer.
Check the program is named (e.g. ‘‘ADDER’’) іп a REM
statement.
ZX81 Sequence
10
11
12
13
14
15
Type SAVE “ADDER” don't press NEWLINE
(ENTER) yet.
Press RECORD and PLAY buttons on the recorder.
Press [NEWLINE (ENTER) ].
Watch the screen.
a) For five seconds it will be grey inversed by diagonal
white lines and if the sound on the TV is turned up
it will be a monotone.
This is the SILENT LEAD IN
b) For ten seconds a horizontal striped pattern appears
on the screen. This is the program going in. A
warbling sound is first heard, then half second
pulses.
с) Тһе screen goes white and the message 0/0 appears,
telling us the computer has transmitted the program
to the cassette recorder.
The ZX81 does not know whether the recording is
successful.
We can only tell by later loading the program back
in.
Stop the recorder
Note the counter reading at the end of the program.
Run the tape forward five more revolutions of the
counter, ready for the next program.
Spectrum Sequence
IMPORTANT NOTE: YOU MUST ALWAYS TAKE THE
JACK-PLUG OUT OF THE EAR SOCKET OF THE
SPECTRUM BEFORE ATTEMPTING TO SAVE A
PROGRAM.
36
10 Key in SAVE “ADDER”.
11 Press ENTER. The Spectrum will print a message on the
screen which tells you to ‘Start tape’, i.e. press RECORD
(or record and play, depending on your cassette
recorder), and “then press any key'. Do so.
12 Blue and red lines (black and grey оп a black and white
TV) will scroll up the border area of your TV screen. This
happens twice as the name of the program is recorded.
When the program is copied, narrow yellow and
blue/black lines roll up the border area. When the
recording is complete an *0 OK" report appears on the
screen. Stop the recorder. Note the tape counter reading.
Your program should now be correctly recorded.
13 On the Spectrum, you can check this without wiping out
the program in memory first. Connect the EAR lead from
the Spectrum to the cassette player EAR socket. Rewind
the cassette to before the start of your recorded program.
Get into the E mode, and key in VERIFY, then enter the
program name between quotes. Press ENTER and start
the cassette on PLAY. The Spectrum displays on the
screen any other programs before the specified one that it
finds on the tape, printing their names on the screen.
14 When the program has finished playing back, an “0 OK’
message means the program was correctly SAVEd, and
*R Tape loading error' means the recording is faulty and
you should SAVE the program again.
15 Run the cassette on five more revolutions of the tape
counter, ready for the next program.
The sequence above assumes a tape counter on your cassette recorder.
Without a counter, the process of finding a program is more difficult.
To place a voice message on the tape, so that the tape is searched for
the voice giving the program name, will prevent the tape being
searched automatically by the computer, but it 1s one possible method.
If used, you should record your voice (most cassette machines have a
built-in microphone) stating the program name several times, then the
program name should be spelt out, the name stated again, and some
cue statement (“saving starts now’) to let you know that after that point
only computer-generated noises exist. This will make finding the
program much easier, as the voice cues occupy a larger length of tape
than a single statement of program name.
The other alternatives are to place only one program on each tape (a
bit uneconomical!) or to leave very large gaps between tapes (30
seconds at least), so that you can search using fast forward/reverse and
are unlikely to miss the gap. This has the advantage that you can set
the computer to search through the tape program by program if you do
miss it. Larger programs should be placed if possible on a side of a
37
cassette by themselves. Short length cassettes are available (5 minutes a
side) to make this a viable option.
Exercises
1 Try a dummy run first. Do not press the recorder keys. Turn up
the sound on the ТУ until you can hear a hum. Awful, isn’t it!
Key in SAVE “ADDER?” and press NEWLINE (ENTER).
(Press a key in response to the message if using a Spectrum).
Watch the screen and listen to the different sounds. When the
screen clears and the 0/0 message appears (0 ОК, 0:1 оп а
Spectrum), key in LIST NEWLINE (ENTER) to get the listing
back.
2 Now SAVE the program on to the tape.
D2: Deleting the Program from Memory
A sure way is to switch off the power - this is not recommended. This
should only be done if the computer needs to be re-set because it will not
respond to commands keyed in. It is much better to use the command
NEW.
NEW
The NEW command deletes any current program and
variables from the computer and clears the screen.
We use the NEW command before we LOAD a program into the
computer from cassette tape, to erase old programs and data from
memory. It is also used to do the same thing, if we have a program in
the computer and wish to clear it out to enter another.
There is another command that only affects the variables store, and
not both this store and the program store, as NEW does.
CLEAR
The CLEAR command erases all the variables in the current
memory.
CLEAR can be used as an instruction in a program, as can NEW, but
since NEW would merely wipe the program its use would be self-
defeating. Try it, if you like the idea of a program that self-destructs!
38
CLEAR is similarly useless in the middle of a program - we would
merely have to re-define all variables.
With our program, if we RUN it, at the end of the run it will have in
the variables store the values of A, B and S. If we then SAVE it, these
values are SAV Ed also. In our case this is irrelevant, since the INPUTSs
will change them when it is used but often it is useful. We can store
data as variables in a program, and not have to re-input values (as long
as certain procedures are followed, as we will see later). This enables us
to have, for example, a telephone directory stored in variables. We
might then use CLEAR to wipe one list, and re-input new data or use
CLEAR before SAV Eing the program to send to a friend for his use.
CLEAR acts slightly differently on the Spectrum (see page 458), but
for our purposes at this point the difference is insignificant. The major
function is the same. It is very easy to key CLEAR by accident on the
Spectrum, so be careful!
Exercises
1 RUN “ADDER”. Enter NEWLINE (ENTER)| to clear
the screen. Enter GOTO 40, then press NEWLINE (ENTER).
The computer will print the value of 5. Now enter
and then GOTO 40 (NEWLINE/
ENTER) again. We then get an error message 2/40 (2 variable
not found, 40:1 on the Spectrum) indicating an undefined
variable, because the computer has wiped the value of S. We will
deal with GOTO in due course. Just follow the instructions for
now.
2 LIST the program ‘‘ADDER”’ on the screen. Press and
. The listing will disappear and the
cursor appears. On the Spectrum, when NEW is followed by
ENTER, the screen will go black for a moment then become
white, with the words ‘© 1982 Sinclair Research Ltd’ at the
bottom of the screen.
3. Press and then [NEWLINE (ENTER) ]. What happens?
Why?
4 Key in the first line of the program and press NEWLINE
(ENTER). Switch off the power supply (by pulling out the jack-
plug). Switch it on again (by re-inserting the jack-plug). What
happens?
5 Re-enter ‘‘ADDER’’.
D-3
39
D3: Loading the Program from Cassette Tape
LOAD “NAME”
The command LOAD “МАМЕ” waits for the cassette to play
the portion of tape with the program called “NAME” and
copies the program, with its variables into the computer’s
memory.
This means that we can start the tape, give the command LOAD
“МАМЕ”, and the computer loads nothing into its memory until the
signal it recognises as NAME appears on tape. We can thus search a
tape for a program. The Spectrum will print on the screen the names of
any programs it finds on tape, before it encounters the specified
program.
LOAD “”
The LOAD “” (nothing between the quotes) command
LOADS the first program it finds on the tape.
N
LOADING PROCEDURE ON THE 4Х81
Place the tape with the desired program in the cassette
player.
Position the tape via the counter to just before the
location of the required program.
Clear the computer’s memory using the
command if there’s a program in memory.
Set the TONE control on the tape recorder to nearly
Maximum (High), and the VOLUME control to %
Maximum.
Key in LOAD “ADDER” or the appropriate name.
Don’t press NEWLINE (ENTER).
Depress the PLAY key on the cassette recorder.
Press NEWLINE (ENTER).
A thin diagonal pattern will appear on the screen with a
single tone sound.
The pattern changes to broad horizontal stripes with
thinner diagonal stripes and half second sound pulses are
heard as the program is loaded in.
The screen clears and а 0/0 message indicates the
loading is a success.
STOP the recorder.
40
10
11
COND л
10
11
12
LIST and RUN the program.
Remove the tape when finished.
LOADING PROCEDURE ON THE SPECTRUM
Place the tape with the desired program in the cassette
player.
Position the tape via the counter to just before the
location of the required program.
Clear the computer’s memory using the NEW command
if there’s a program in memory.
Set the TONE control on the tape recorder to nearly
MAX (High), and the VOLUME control to % MAX.
Key in LOAD ‘‘ADDER’’, but don’t press ENTER yet.
Press the PLAY button on your cassette recorder.
Press ENTER.
When the Spectrum has found a program it will scroll
blue and red bands of colour up the border area. The
name of the program will be printed to the screen and
then the blue and red lines repeated again. If the correct
program has been located, then it will LOAD with a finer
set of blue and yellow lines scrolling up the border area.
If not, the border area will flash blue and red alternately
as it carries on to the next program on the tape.
When the program is correctly loaded, the phrase:
0 OK, 0:1
will appear at the bottom of the screen to indicate that all
is well.
Stop the recorder.
LIST and RUN the program.
Remove the tape when finished.
CAUSES OF FAILURE TO LOAD
1
3
Volume too low.
Volume too high.
Tone too low.
These indicate that the program has been played at the wrong
settings. New volume and tone adjustments will have to be
made. Some indications of these problems are visible on the
screen display of the ZX81, although systems vary in their
response. Appendix IV has a procedure for adjusting tone and
volume settings for the ZX81, as well as some general hints on
tape use. Experiment and get to know the patterns produced
during LOAD on your ZX81.
41
4 Loading started in the middle of the program. If a mistake has
been made with the start position, rewind the tape completely
and let the computer search for the program name.
5 The program is not on the tape. Check your directory, and the
writing on the cassette.
6 Тһе program name is incorrect. Try again, making sure you
have spelt it correctly in the LOAD instruction. If you fail again,
run through the tape using the LOAD ““””' command. This will
load the first program each time. Stop the cassette player after
each load and LIST the program to check. (This is not necessary
on the Spectrum.) If it's not the program you want, repeat for
the next program on the tape. The Spectrum will print the name
of all programs оп tape if you use a LOAD “ZZZ” instruction,
i.e. a name that does not exist as a program name.
7 Pick up from stray electromagnetic fields.
This will show as violent interference on the screen, distorting
the patterns together with excessive hum on the sound. It could
originate from the ГУ itself, feedback between the recorder and
the computer or an external field. Switch off any radio that is in
the vicinity. Take out the jack-plug from the MIC socket of the
cassette player, as this will break the feedback loop that can exist
between the computer and the cassette player.
The Spectrum has fewer LOADing problems than the ZX81. It will
accept a much greater variation in both the volume and tone of the
signal. However, it is worth noting that if there are great differences
between the recorder the tape was recorded on and the one it is played
back on (variations in tape-head azimuth is often the main source of the
problem), then LOADing can be almost impossible, even on the
Spectrum.
As we noted at the beginning of the book, the Spectrum, unlike the
ZX81, offers a choice of upper and lower case letters. Ensure that if
you have used lower case ones in the program's name, then you use
them again in the LOAD “ххх” command. The same applies if you
use upper case letters to name a program. Thus, a program named
“MATHS” will not LOAD with the statement: LOAD ‘‘maths’’.
Some further information concerning the use of cassette tapes, and
advice for the ZX81 if problems are encountered is given in Appendix
IV.
Exercises
1 Load the program “ADDER”. LIST and RUN it.
Delete it from memory, using NEW.
Try loading it with different volume and tone setting.
Estimate the volume and tone ranges for which it will not load. If
you have a ZX81, you can do this by watching how the screen
42
patterns change when you change the settings while the program
is loading. Read Appendix IV.
D4: Listing the Program on the Printer
LLIST
LLIST lists the program currently in the computer memory
on the printer, starting from the first program line.
LLIST N
LLIST N lists the program on the printer starting from line
N.
We can stop the listing by pressing (BREAK needs CAPS
SHIFT on the Spectrum). This stops the listing with an error message
D/line number on the ZX81 and D BREAK - CONT repeats 0:1 on
the Spectrum.
It is important that you keep a listing or printed record of all the
programs you write or use. The listings are a great help in debugging
programs (both under development and if there are problems
discovered later). We can key the program back in from this listing, if
necessary.
Printouts also form part of the documentation for a program and
should be pasted into a notebook. Printed records of program results
can also be kept using the COPY command.
Exercises
1 LLIST the program ‘‘ADDER”’ on the printer.
2 ‘Try stopping the listing with the BREAK key. The listing cannot
be continued by pressing CONT (try it). On the Spectrum,
despite what it says, this doesn't work. The screen just goes
blank. Don't worry. Press BREAK again.
3 List the program on the screen. Use the COPY command to list
the program on the printer.
What is the difference between the two listings obtained with
LLIST and COPY?
43
D5: Program Libraries and Directories
LIBRARY
A collection of programs stored on cassette tape. For example:
COMPUTERLAB PROGRAM LIBRARY
or Your own program library.
Notice that programs can also be stored on magnetic discs and im
ROM memories.
DIRECTORY
The list of program names in the library together with
important information about them. Another name for a
directory is CATALOG.
You should keep, in your notebook, or a special book, a directory of all
programs you have entered and saved on tape. This will seem a bit
pointless when you only have a dozen or so, but you will appreciate the
need to be systematic when you accumulate a large number.
PROGRAMS YOU WRITE
Each program you write should be
Named.
Saved on a cassette tape.
Listed on the printer.
Documented.
Catalogued into the Directory of your own program
library.
Gm wm G3 N =
DOCUMENTATION
The complete collection of information about the program or
file, written on paper. The information should include:
1 What the program does.
How it does it.
A listing.
A flowchart.
How to use it.
When it was written and by whom.
Q3 Gr мы CS N
44
We will introduce flowcharts in Section G.
DIRECTORY LAYOUT
A typical layout for the Directory Section of your notebook
would be:
Program Name: MOONLANDER
Cassette Name: GAMES 3
Locatton: 100-120
Program Length: 30 lines
Date Created: 18.5.82
Author: PAUL NIXON
Function: Lands a spaceship on
the moon
WRITING ON THE CASSETTE
There is a label on each side of the cassette. Write on each
side:
1) Cassette name or code.
2) Date.
3) Program names as they are copied into it. Make sure
these are correctly spelt!
Your directory should provide you with the more detailed
information, such as precisely where the program is to be
found.
45
SECTION F: IMPROVING THE PROGRAM
E1: Adding Comments
REM
The REM statement is used for adding comments to a
program. All REM statements are ignored by the computer
when the program is RUN.
These comment statements are for the users’ benefit only.
They contain information in the text of the program which
explains what the program is doing. For example:
REM **THIS PROGRAM ADDS TWO NUMBERS
KEYED IN AND PRINTS THE RESULTS**
Notice the use of the asterisks to separate the text from the
instruction.
100 REM ** END OF PROGRAM**
The complete program including all REM statements appears on the
screen or printer when using the LIST and LLIST commands.
Our saved program so far looks like this:
5 REM “ADDER”
10 INPUTA
20 INPUT B
30 LET S=A+B
4) PRINTS
Let us add some additional REM statements:
6 REM **THIS PROGRAM ADDS TWO NUMBERS
KEYED IN AND PRINTS THE RESULT**
60 REM **END OF PROGRAM**
Key these extra statements in. LIST the program and RUN the
program.
Do not worry about the line numbers not being in intervals of 10.
We will renumber the program when we have added all the extra lines.
E2: Using the Print Statement
PRINT
In our simple program we will use the PRINT statement:
a) To print messages and instructions to the user on the
screen:
7 PRINT “INPUT TWO NUMBERS"
The message INPUT TWO NUMBERS is a string, and
will be printed without the quotes.
46
b) To print the numbers keyed in and the result:
40 PRINT A; ‘‘ + ’’;B;‘* = ?°;5
A and B are the names of the variables to which the
numbers keyed in are assigned, and S is the variable that
stores the sum of A and B, i.e. the result. Variables do
not need quotes to be printed.
The semicolons (;) tell the computer that we want close
printing, with each print item (character or variable)
directly after the last, with no spaces between. The
inverted commas (quotes) enclosing the symbols + and
= means we want those symbols printed.
c) To leave spaces between lines printed on the screen:
8 PRINT
The PRINT instruction used on its own prints an empty line
on the screen.
Note that we have changed line 40 from what it was previously. Our
program now looks like this:
5 КЕМ “ADDER”
6 REM **THIS PROGRAM ADDS TWO NUMBERS
KEYED IN AND PRINTS THE RESULT**
7 PRINT “INPUT TWO NUMBERS”
8 PRINT
10 INPUT A
20 INPUT B
30 LET S=A+B
40 PRINT А‘ + ‘В; = > 58
60 REM **END OF PROGRAM**
Key in the new lines and RUN it.
E3: Adding a Loop
GOTO N
The statement GOTO N transfers program execution to the
specified line number, N. For example:
50 GOTO 7
When we insert line 50 into our program we can see that, after printing
the result on the screen, line 50 sends the computer back to line 7 to
execute the program again from that line, and as soon as the computer
reaches line 50 again it is sent back to line 7 once more.
We have constructed a LOOP. The program is going to carry on
looping forever unless we can pull out of it.
47
Our program now is:
5 REM “ADDER”
6 REM **THIS PROGRAM ADDS TWO NUMBERS
KEYED IN AND PRINTS THE RESULT**
7 PRINT “INPUT TWO NUMBERS”
8 PRINT
10 INPUT A
20 INPUT B
30 LETS-A-«B
40 PRINT A;" &'B;"UeCUNS
50 GOTO 7
60 REM **END OF PROGRAM**
Key in line 50. RUN the program. When you are tired of inputting
numbers, read on.
E4: Stopping the Program
We need to know how to get out of the input loop between lines 7 and
50. The program will wait for an input of a number at line 10 INPUT
A. The cursor will appear on the screen.
To pull out or stop the program at this stage key in [STOP |
[NEWLINE (ENTER)]. STOP is a command we input directly, like
RUN.
STOP
On the ZX81 the STOP command stops a program with the
message: D/line number, and on the Spectrum we get H
STOP in INPUT (Line number):1.
The line number refers to the program line the computer
was executing when it was stopped.
Our program will give D/10 as the message (H STOP in INPUT 10:1
on the Spectrum). We can cancel the STOP command and continue
the program with the CONT command.
CONT
The CONT command used after the STOP command will
continue the program from the line the program was stopped
at.
48
Keyin ICONT | INEWLINE(ENTER)| to continue the program. Note
the Spectrum prints CONT in full as CONTINUE.
Exercise
Run the program “АОПЕК”.
STOP the program when the first | L | cursor appears.
CONTinue the program, and input a value for A.
STOP the program when the second cursor appears. Note that
the line number is different in the message that appears on the bottom
of the screen.
CONTinue the program.
E5: Testing for a Condition
In a program we can make decisions which will affect what the
computer does next. A decision is made on the basis of whether a
CONDITION is true or false.
CONDITION
A condition has the form (X) (condition) (Y) where X and Y
are numbers, variables or expressions and the condition is a
conditional operator. We shall use only the = (equality)
operator for the moment. The following are all conditions:
X=Y
A = 23
B = 2*3
Conditions are tested and the next action determined by the result of
the test with the IF and THEN statements used together.
IF - THEN
An IF - THEN statement has the form:
IF (condition) THEN (instruction)
For example: IF А = B THEN PRINT “EQUAL”
IF A=@ THEN LET A= 3
The instruction can be any valid instruction. The statement
means:
IF (the condition is TRUE) THEN (perform as instruction).
IF (the condition is FALSE) the computer ignores the
instruction after THEN and goes to the next line of the
program.
49
In our simple program we can use the IF — THEN statement to insert
in the program a conditional test which will stop the loop, without
using the direct commands which we used in the last Unit. To STOP
the program in the same way as with a direct command we can insert
another line:
15 IF A«9 THEN STOP
This tells the computer that IF A = 0 (if it is TRUE that A is equal to 0)
THEN it should STOP. IF A is any other value (if it is FALSE that
A = 0) it ignores the THEN STOP instruction and moves to line 20.
Enter this line into the program. RUN the program.
Enter different non-zero values for A to see that if A 1s not zero then
the program continues as before. Enter .000000001 to see that only if
A is exactly zero will the STOP instruction be executed. Input 2 for B,
and notice that the result is given as 2. This is due to the fact that
calculations are only performed to a certain degree of accuracy.
Enter .0000001 for A, and input B as 2. The computer returns
2.0000001 as the value of S- the number is within the limits of
accuracy.
Now enter 0 for A. The program will stop, just as when we entered
STOP as a direct command. Notice, however, that the message at the
bottom of the screen is different. We get the message 9/15 on the ZX81
(a STOP statement, 15:2 on the Spectrum).* The message is different
because STOP in a program means “f the CONT command is
received, proceed with the next program line', since if it continued with
the same line it would just STOP again! As a direct command,
however, STOP means ‘if the CONT command is received, start with
the same program line', so that the computer does not miss out a
program line.
Now we have some extra control over the program, but it is still not
satisfactory. We used IF A - 0 because in this program it is not a value
we are interested in seeing added to B (a value used in this way is
known as a DUMMY or SENTINEL VALUE - a value just used as a
signal to the computer which would not need to be entered in the
course of normal inputs). This stops the program and we can continue
it, but the program just goes back into the loop. We need a method of
proceeding out of the loop to end the program, or continuing with more
program lines.
We can do this with a STRING CONDITION. The conditional
operators can also be used to express relations between strings - either
string variables or simple strings.
We insert the following lines:
30 PRINT “RUN PROGRAM AGAIN ?(YES/NO)"
55 INPUT A$
56 IF АЗ - ““ҮЕ58” THEN, GOTO 7
“Оп the Spectrum, the statement after the THEN іп an IF- THEN statement is
treated as the second statement in the program line. This is why we get 15:2, meaning
line 15, statement 2. This is the only instruction used in the main text of this book
(before Unit W2) where the statement number will not be 1 in an error message.
50
When the program gets to line 50 it will print out the message, and
then put the cursor at the bottom of the screen. Because it has been
told that a string input is to come, the cursor has quotes either side:
"[L]". There is no need to type quotes. Whatever characters are
typed in will be stored as A$. The string is entered by pressing
NEWLINE (ENTER) after keying in the characters. Line 56 tells the
computer to check if the characters in A$ are the same as the characters
of the string ‘‘YES’’. If they are it goes to line 7. If they are not the
program will continue to line 60. Notice that any string other than
“YES” will cause the program to continue to line 60.
Exercises
1 Delete line 15 in our program, which we no longer need.
Insert the new lines 50, 55 and 56.
3 RUN the program. Enter “YES” in response to the string input
cursor and see that the program loops back to line 7.
4 Next enter “МО” to see that the program goes to line 60 and
gives the message 0/60 (0 OK, 60:1 on the Spectrum). Run the
program again. This time enter anything other than ‘ҮЕ’ or
“МО”, to see that the program goes by default to line 60 if
anything other than ''YES"' is entered.
5 Experiment with the string input. What happens if you press
NEWLINE (ENTER) without inputting anything? What
happens if you try to key in quotes around the string?
6 LLIST the program on the printer. The development of our
program is complete, and we have run it to see that it works. It
remains to renumber the lines, and this is easier to do if we have
a listing.
E6: Final Edit and Saving
Our program ‘‘ADDER”’ is complete and works. We need, however,
to renumber the lines. The procedure for this is as follows:
1) Using the listing from the printer, renumber the statement lines
in tens at the side of the old number. You can also count the
number of lines in the program on the screen display, and
multiply by ten to get the new highest line number. For our
program, this will be 120.
2) a) List the program on the screen.
b) Usethe ^4 and | cursor control keys to bring the current
line cursor to line 60 (the bottom line of the program).
c) Press EDIT and pull line 60 down to the bottom of the
screen.
d) The new HIGHEST line number is 120.
e) Change 60 to 120.
31
g)
h)
J)
Press NEWLINE (ENTER). Line 60 remains, but it 1s
duplicated by the new line 120.
Delete the old line 60 by entering 60 and pressing
NEWLINE (ENTER).
Change each line number in this way, going from highest to
lowest.
Lines that contain other line numbers must have these
changed to their new numbers. In our program we must
remember to change line 56 to:
90 IF A$=‘‘YES’’ THEN GOTO 30
where 3@ is the new line number corresponding to the old
line 7.
Rename the program ‘‘ADDER2’’, at the same time as you
change the line number of line 5 to 10. This program is
different from the original version, and must be given a
different name both for our reference, and the SAVE and
LOAD operations.
Run the program to check that it still works, and that we
have all the lines, with any GOTO (line number)
statements correctly renumbered.
LIST and LLIST the program.
SAVE “АОПЕК2”.
Write the name of the program on the tape cassette, along
with the tape counter readings.
Put details of the program in your directory.
Stick the listing of the program in the notebook you are
using for documentation.
52
SECTION F: A GAME INTERLUDE
F1: The Program Library
In addition to the many programs and subroutines in the main body of
the text, there are additional applications and games programs in the
Program Library (Appendix VI). Our main objective is to enable you
to write your own programs, and the programs in the text have been
used to illustrate the use of techniques. Some are functional (do
something significant) and some are just illustrative. You don’t have to
key all the programs in the text into the computer, but you must
understand them. However, you should key in all the shorter programs
since it’s important to see how different types of program operate in
practice. Analysing the longer programs is vital, even if you don't key
them in. The use of flowcharts (to come in Lesson G) is helpful for this.
There are also suggestions for programs you should write, to get
practice in writing programs to perform tasks, after units dealing with
specific techniques.
The programs in the library are examples of applications and games
programs, plus a number of subroutines for some of the manipulations
commonly required in programs. You can key these in at any time if
you want to see how the program works, find the program useful, or
want to play the game. Once keyed in you can SAVE them on cassette
and LOAD them back in quickly. None of the programs are very long,
since it is difficult to analyse long programs, and this is what we want
you to do. Keying in a program from a listing doesn’t teach you
anything about programming, nor does running it. Writing or
modifying a program does! We hope you find the programs
entertaining or useful, but please treat them as a source of ideas and
illustrations about programming, not as a fixed set of optimum
solutions. Programs can always be improved!
Be careful when keying in programs, especially if you don't
understand how they work. (It might be better to work this out
first - because, to labour the point, that way you'll learn something.)
The S-cursor will mark some errors in lines for you and stop you
entering them, but there are always other problems you can introduce.
Check through your listing for errors and missing lines (surprisingly
easy to do, even with numbered lines) before you run the program.
You must also be careful to check that any necessary alterations have
been made to the program if you are going to run it on a Spectrum, as
noted in Unit W2. These are mostly minor but can be crucial.
F2: A Game to Key In
You have now spent a lot of time working through the essentials of your
computer system and its BASIC, and you probably have the feeling
53
that thus far you haven't seen anything to persuade you that computers
are particularly exciting machines. Far from being impressed by their
capabilities, you may well be thinking, ‘What’s so good about a
computer if you need to do all this to get it to do something that I could
do in my head when I was six?’ Well, the following program may not
be earth-shattering, but it does in fact reveal a fairly complex set of
computer operations, as well as providing amusement. The program is
called **BUG"' and it enables you to play a game that consists of
dropping bricks from a height to squash the 'spider' (an asterisk)
scurrying along below. If you have a militaristic or SF streak in your
nature, or are an arachnid lover, feel free to change the name to
“BOMBER” or whatever (in line 5). Whether you will enjoy it more
by pretending you're napalming Venusians is your affair. It won't
alter how the program works!
To play the game, however, you first have to key it in. You won't
understand at this point how it works (and won't for a few chapters
yet), so you have to rely on keying it in exactly as listed. Like all the
programs in the text, this one will look somewhat different on the
screen or in a printer listing, since for clarity we have not reproduced
the printer listings exactly, since printouts tend to contain broken
words (when one line on the screen is full and the computer runs on to
the next) and other possible confusions. Check each line carefully
before you press NEWLINE (ENTER), and pay special attention to
the punctuation. Notice that there are 2 spaces before the asterisk
(spider) in line 50, and 3 spaces either side of the <=> (brick
dropper/intergalactic space hod) in line 60. If you have any difficulty
finding the right modes and keys for the characters you need, refer to
the list in Section B (ZX81) and Unit W1 (Spectrum). It is very easy to
end up typing a keyword instead of inputting it directly when you are
keying in a listing (typing T,O instead of inputting TO, for example).
If you do this it is not clear why you get the cursor indicating an
error, since the line /ooks the same as the listing, so be warned.
ZX81 Users! Notes
The graphic character in line 160 is an inverse asterisk, (SHIFT B in
Graphics mode) and in line 190 the characters are the SHIFTed
graphic on the T key, the asterisk again, and the НІЕТеа graphic on
the Y key. The comments in square brackets are intended to be helpful,
not to be entered!
Spectrum Users’ Notes
Line 60 has an inverse video asterisk. Го get this, key CAPS SHIFT
and the 4 key to get INV. VIDEO. Then input the asterisk. Use CAPS
SHIFT and the 3 key to get TRUE VIDEO, i.e. normal black on
54
white, back. If you don't return to normal video, the quotes will be in
Inverse, and so will everything after it.
Line 190 has the unshifted G mode graphic on the 6 key, and then
the CAPS SHIFT graphics on the 8 key and the 6 key as the graphics
string.
5 КЕМ "BUG"
10 LET 5-0
20 LET B=10
30 FOR N-1 TO 12
40 LET C23 L
SQ PRINT AT 2O»C-2;" +" [2 Spaces #]
60 PRINT AT (ЗЕ-2;" <=> и [3 5р, =>, 35 Sp]
70 IF INKEYS ="6" THEN GoTo
150
80 LET B=B+(3 AND INKEY$ -"&"
AND B<28)-(3 AND ІМКЕҮФ =
"=" AND B»3)
90 LET C=C+ INT ( ЕМО *2+1)
100 IF C<30 THEN GOTO 50
110 CLS
120 NEXT N
ie ERE np 1g RER "9! — DSCUREDIEM % SRATI
140 STOF
150 FOR F=4 TO 20 ЕТЕР 4
160 FRINT AT Е,Б+1;"Ш" AT [Inverse %1
FsB*1;" "
170 NEXT F
180 IF E+1 <> C THEN GOTO 50 Г <> іс one character]
190 PRINT AT 20»C-1; "EF"; AT
2130-2; "SPLAT"
200 CLS
210 LET S=54+1
220 GOTO 120
When you've got it all keyed in, LIST it to check it through again.
Check the first screenful, then (on a ZX81) LIST 170 to get the rest of
the program (with a line that was on the first screenful to keep your
place). LLIST it on the printer.
Key RUN then NEWLINE (ENTER) to play. The keys 5 and 8
move you left and right respectively across the top of the screen. ‘They
are chosen for the direction of the arrows printed on them. Key 6 will
drop the brick. If you hit the spider it goes splat and you score a point.
You have to hold the keys down to ensure that the computer will read
the keys and perform the right operations. This is because it reads the
keys only once in each pass through the loop (lines 50 to 100), апа
might miss the input otherwise.
When you’ ve played the game a few times, SAVE it on to tape and
catalogue it.
55
|
——————— ph
wrt
- ot 740 | 7% 03:
2. -— ` 1484 4973
^c, з
I E
á ja %
“4: 5
i э pis * Ж | c
° m L
474 f ° I
TL à
é ” ' /
F | L 1%
и.
i í
í А б =,
i ` Wf i r ; 4 ъ
PART TWO
ESSENTIALS OF
BASIC PROGRAMMING
SECTION G: PROGRAMMING METHODS I
G1: Programming
Now that you can operate your computer and have written a short
program we must look in greater detail at the activity we call
PROGRAMMING and study how:
COMPUTERS SOLVE PROBLEMS
To enable them to do this we engage in the two main activities of
programming:
1 PRODUCE THE METHOD FOR SOLVING THE
PROBLEM
2 PRODUCE A WORKING PROGRAM
The method for solving our problem is called an ALGORITHM. An
algorithm 1s like a cookbook recipe, and is written down in steps in a
brief English style we call PSEUDOCODE, and the method by which
we arrive at the recipe is called STRUCTURED PROGRAMMING.
We break the problem up into smaller sub-problems or sub-tasks in
a step by step, modular fashion, starting from the simple initial
statement of the problem and working down to lower levels of greater
complexity (i.e. in a TOP DOWN manner). As we refine our problem
our steps become more like the operations the computer can perform.
Our final description of the lower level of the algorithm will be in terms
of the control and other structures of the language.
To help us produce the algorithm we use STRUCTURE
DIAGRAMS. The simplest of these is a TREE diagram. The
pseudocode description of the algorithm is easily written down from the
descriptions of tasks in the tree diagram. We cannot
key the pseudocode description of the algorithm into the ZX81 or
Spectrum because it will not understand it, and there is no means of
doing it anyway. We have to translate each section of the pseudocode
into its equivalent in the BASIC language, which the computer
understands, to produce a PROGRAM.
For the computer to be able to run the program successfully and
produce the results we require, there has to be a LOGICAL FLOW to
the program. This is often difficult to see from the structure diagram,
and so we use another diagrammatic technique to illustrate the flow of
control through the program, i.e. determine the order in which the
program modules or sub-programs are processed and the order of
coding the specific instuctions within a module.
This technique uses FLOWCHARTS. These are important for
documentation purposes and are in common use. We will describe
them shortly.
59
Producing a working program involves running and DEBUGGING
(correcting errors in) our first effort. We then have to TEST the
program with sample data and finally DOCUMENT it. In this first
section on methodology we shall consider problem solving and coding
the algorithm in BASIC in more detail.
You will see that the first half of the activity we call programming is
LANGUAGE INDEPENDENT. Having produced our problem
solving method - the algorithm — we can code it into any computer
language we wish. We need to know the language thoroughly and how
the fundamental programming structures we have used in the
algorithm - decisions, loops, subroutines, subprograms,
functions — can be implemented in that version of the language which
runs on the computer we are going to use.
In this book we are using the ZX81 or Spectrum computers. The
versions of BASIC are slightly different. All that this means is that
whilst the algorithms to be coded for both machines will be the same,
the final programs may be slightly different.
Our algorithms and their representation in pseudocode and
flowchart form are thus PORTABLE from one machine and language
to another.
Good coding habits are also important. There are good and bad
ways of turning the solution to a problem into a working program.
Style, presentation, ease of understanding, modularity, efficiency are
all important. Throughout our book the emphasis will be on correct
problem solving techniques and good programming practice, while you
gain a thorough knowledge of BASIC.
Here is our first rule of programming:
PROGRAM CORRECTLY FROM THE START
Remember - bad habits die hard!
The material in this Section may initially appear dense and difficult
to follow. Work through the text carefully, and refer back to this
Section as often as you feel necessary, when each of the topics covered
in the following Sections (dealing with the essential groundwork of the
BASIC language) has been introduced. The exercises given in the text
should be used to put into practice both the specific techniques involved
and the general approach to programming presented here.
G2: Problem Analysis
Producing the algorithm, or method of solving the problem, is often the
most difficult part of programming because it involves the most work.
From the start careful planning and organisation are absolutely
essential. The task is simplified when a structured design method is
used, coupled with a diagrammatic representation of the algorithm
60
using a structure diagram or flowchart. The actual coding of the
program in BASIC using the available language instructions is then a
straightforward matter.
To produce the Algorithm we must:
STATE THE PROBLEM
RESEARCH THE PROBLEM
DESIGN THE ALGORITHM
DESCRIBE THE ALGORITHM IN PSEUDOCODE
AND FLOWCHART FORM
= һі = =
A GO м м
Let us now consider each of these steps.
1.1 State the problem fully
1.1.1 STATE THE PROBLEM
1.1.2 UNDERSTAND WHAT IS TO BE DONE
To solve any problem we must know what the problem is and what is to
Бе done. We later work out how to do it. A complete statement of the
problem should include:
(i) What information or data is to be input.
(i) What answers or results are to be output.
(uni) What operations аге to be performed on the data.
At this stage a precise description of (111) may not be available.
EXAMPLES
Problem: Write a program which will print out the sum and
average of five numbers input at the keyboard.
Problem: Using the computer produce a telephone directory to
contain up to fifty entries, which may be updated and
assessed in an enquiry mode.
In the first problem the input data, output data and operations are easy
to see. The second is much more complex and needs more researching
and information.
What we are trying to do in 1.1.1 and 1.1.2 is to initially specify the
problem as exactly as possible. When we analyse the problem further
we may have to go back and ask for more information 1.e. a more
detailed specification.
61
1.2 Research the problem
1.2.1 RESEARCH AND ANALYSE THE PROBLEM TO
SEE HOW THE COMPUTER CAN HANDLE IT
1.2.2 IDENTIFY ALL FORMULAE AND RELATIONS
INVOLVED
1.2.5 IDENTIFY ALL DATA INVOLVED
Here we start to determine how the computer may solve the problem.
We need to find out and write down:
(1) What formulae and expressions are to be used.
(п) What kinds of data are involved - numeric, string, etc.
(ui) What functions are involved.
(iv) What is input and output data.
(v) What is the form of this data.
(vi) How much data there is.
(vii) What processing is to be done and how many times.
It is useful at this stage to start to create a data table (a table of variables,
constants and counters), to record how we are going to store the data.
Other questions we will ask when we are a little more experienced are:
Have I solved a problem like this before?
Can I use my solution or modify it?
Has anyone else solved it?
Where can I find their algorithm or program?
ALL THE FACTS OBTAINED FROM RESEARCHING
THE PROBLEM SHOULD BE JOTTED DOWN
We can now begin to design the algorithm in a structured manner.
1.3 Design the algorithm using structured methods
1.3.1 BREAK THE PROBLEM DOWN INTO
SUB-PROBLEMS
1.3.2 USE A STRUCTURE OR TREE DIAGRAM TO
HELP
1.3.3 CLASSIFY MODULES OR PART MODULES AS
— INPUT
— PROCESSING
– OUTPUT
USE FUNDAMENTAL CONTROL STRUCTURES
SET UP A DATA TABLE
REFINE THE ALGORITHM UNTIL CODING
INTO BASIC IS AN OBVIOUS EXERCISE
кі = =
92 G3 Go
HD Qv >
Structured programming means designing the algorithm in a top
62
down, modular fashion, with step by step refinement of the solution
starting from the single statement of the problem which we place at the
highest level. We break the problem into sub-problems at successive
lower levels. Each sub-problem or module is one that can be solved
individually. Structure diagrams or tree diagrams are useful as a
representation of this refinement process.
G3: Structure diagrams
These enable us to break down the problem into distinct tasks and sub-
tasks which eventually become simple enough to be coded directly in
BASIC instructions. One form of these diagrams is TREE
DIAGRAMS. The tree diagram has its trunk at the top of the page.
We call this BOX 1 and give it the title: TASK TO BE DONE. We
could have called it ‘problem to be solved’.
For example, make a cup of tea or find the average of five numbers.
We next break down the task into things to do. These are sub-tasks
and each has its own box. For example:
BOX 1.1: First thing to do
BOX 1.2: Second thing to do
Each sub-task is broken down into further sub-tasks: 1.1.1, 1.1.2 etc,
each with their own boxes, the things to do placed in them becoming
progressively more exact and simple.
Breaking down a task into a tree diagram:
first
level
second
level
її 1.2 145
FIRST THING SECOND THING LAST THING
pO TO DO
third
level
ERE И Е. 1.2.1 1.2.2 3.253 4,2,2 L. 39
Sub- Sub- Sub- Sub- Sub- Sub- Sub-
task task task task task task | task
The sort of programs you will start to write in BASIC are sequential,
that is to say things are done one after another, so you need to be able
to indicate that the program should first do one thing, then a second,
then a third . . . and so on. You do this by drawing the boxes which
63
contain the tasks to be done in a straight line across the page next to
each other for example:
The numbers contained within each box identify where the box is
placed on the tree. Take for example:
The first digit shows it comes from the first level 1 ‘What is to be
done’.
The second digit ‘2’ shows it has come from the second level box 1.2
‘Second thing to be done’.
The third digit ‘3’ shows this box is the third sub-task in the
sequence derived from which in turn is derived from . Into
the boxes go brief statements of the actions needing to be performed.
These are general statements at the top of the tree, e.g. ‘Get Sum of
numbers’, but become more specific at each lower level, so that ‘Get
Sum’ is broken down in the operations needed to produce the result
‘Get Sum’, e.g. ‘Input first number’, ‘Input second number’, ‘Add
the two numbers’. Finally the instructions become detailed enough to
form our English language ‘pseudocode’ which can be written out,
ready to be translated into BASIC instructions.
AN EXAMPLE OF TREE DIAGRAM DESIGN
Here is an example to try out. Suppose we have a robot with arms, legs
and eyes which we want to program to make a pot of tea. Our major
task for the robot is:
1
Make а Pot
of Tea
This can be broken down into sub-tasks which we put in order across
the page:
1
МаКе а Ров
of Tea
Les
Put Water
in Pot
Each of these sub-tasks is still far too complicated for our robot to do.
We must break the problem down further. Breaking down 1.1 into sub-
tasks we get:
те Ме 1.1.2 11.3
Fill the Kettle Plug in Kettle Wait Until
with Water and Turn On Water Boiling
The robot also needs to be told how to fill the kettle so we break this
down as:
1.2.1
Fill the Kettle
with Water
у 9000. Т МИК:
Wait Until
Full
L. L La L
Put the Kettle
Under Tap
On the next page is a complete tree diagram. Certain things are still
wrong with this algorithm for our robot, but it does show you how a
problem can be broken down.
G4: Classifying Program Modules
Most computer programs involve:
INPUT
PROCESSING
and OUTPUT
activities.
As we are designing our programs and forming modules, it becomes
evident from our pseudocode description of the algorithm which of the
above functions the modules should have. Depending on the problem
and the result of our algorithm design, modules may be separately
65
99
T La
Boil Water Put Tea
the Pot
Loan әш,
Wait Get Tea
Until Pot
Water
Boiling
i E:
Put Water
into the Pot
Lk ЖЕ!
Take
the Pot
to the
Kettle
designated input, processing, and output functions or may have these
functions nested as sub-modules.
Module 2
PROCESSING
Module
OR
Module І
Module 2
PROGRAM
G5: Control Structures
PROCESSING OUTPUT
Control structures are the statements or groups of statements
(modules) in a program and algorithm by which the order of processing
is controlled. Using them properly is the most important part of
programming.
BASIC is a line numbered language. The order of processing in a
program is from the lowest line number in the program sequentially
through to the highest, unless this is changed by using a control
structure. Control structures link the different modules in a program
together and are themselves modules. They will be dealt with in depth
in the remainder of this section.
To make our algorithm language-independent we can write them
using a standard notation in pseudocode for the particular control
structure together with its flowchart description. When we code the
structures into the BASIC language the instructions used and the order
of statements in the structure may be slightly different according to the
version of BASIC and how ‘structured’ it is (i.e. how easily it
accommodates these control structures). The structures we will study
in BASIC are:
(i) DECISION STRUCTURES
(ii) TRANSFER STRUCTURES
(iii) LOOPS
(iv) SUBROUTINES
(v) NESTED STRUCTURES
(vi) SUB-PROGRAMS
67
DECISION STRUCTURES
Computers make decisions by comparing the value of one variable
against another. For example:
IF А-0 THEN (do something)
IF AS = “YES” THEN (do something)
To make decisions they use relational (or conditional) and logical
operators, like the equals operator above.
Sinclair BASIC uses three decision structures:
Simple decision
Double decision
Multiple decision
As a result of these decisions control may be transferred to another
program module, or local processing within the structure may take
place.
TRANSFER STRUCTURES
These structures involve:
(i) UNCONDITIONAL TRANSFER
which is a direct transfer of control using a GOTO (line number)
statement. Transfer is to another program statement or a module
consisting of a group of statements. GOTO is a very powerful structure
and must be used with care.
(п) CONDITIONAL TRANSFER
in which transfer of control to another segment is made as the result of
a decision: i.e. IF (condition is true) THEN GOTO (line number).
These program structures are discussed further in Section H.
LOOPS
The need for the repetition of simple tasks is one of the fundamental
reasons computers exist. Loop structures are incorporated in most
computer programs. A loop is a sequence of repeated steps in a
program. This repetition must be controlled. We shall see in Section L
that repetition is controlled by:
(i) COUNTING
(ii) TESTING FOR A CONDITION
68
There are three common loop structures:
(i) Repeat (the process) forever!
(ii) Repeat (the process) until (a condition is met).
(ui) While (a condition holds) repeat (the process).
Structure (i) is of little use, except that we have to note it and make sure
it does not occur.
In structure (11) the condition is tested after processing.
In structure (iii) the condition is tested before processing.
Sinclair BASIC uses a convenient and powerful set of statements for
controlling repetition by counting called:
FOR - NEXT Statements
SUBROUTINES
Structured programming involves breaking down а complicated
problem into subproblems which can be worked on separately.
SUBROUTINES are such separate independent program modules.
They are distinct from SUBPROGRAMS which have similar
properties in that they are routines or groups of program statements
that are repeated more then once during a program run.
Subroutine modules have a unique address and can have a name
(like a person who lives in a house). Transfer of control to the
subroutine from the MAIN PROGRAM, when the program runs is by
reference to the subroutine address through a special SUBROUTINE
CALL INSTRUCTION. This is the GOSUB (address of subroutine)
statement.
A return of control to the main program to carry on processing from
where it left off is through a special instruction: RETURN.
Subroutine structures in Sinclair BASIC are explained in Section N.
NESTED STRUCTURES
These are program modules or structures that lie entirely embedded
within each other (like a set of Russian dolls).
A simple nested structure 1s
MODULE 1
MODULE 2
MODULE 3
69
In terms of program statements this would look like:
module 1
Inn 222 s,
20
module 2
40
. —
BE ыз шч
module 3
SEL CIIM 2
80
IUD
Ш.
120. — ———
ГІП...
140. 1.
The flow of control is:
START MODULE 1
TRANSFER CONTROL ——— 9» START MODULE 2
TO MODULE 2
TRANSFER CONTROL —————» START MODULE 3
TO MODULE 3
ү? COMPLETE MODULE 3
TRANSFER CONTROL
BACK TO MODULE 2
COMPLETE MODULE 2
TRANSFER CONTROL BACK
Subroutines, subprograms, loops and decisions may be nested in
programs. Nesting is dealt with more fully in Sections H, L and N.
G6: The Data Table
When designing a program it is important that our knowledge of the
data and information pertaining to the problem is complete. All data
will need to be assigned a VARIABLE name, unless it is a numeric
constant used in a formula.
70
The variable type will be either:
NUMERIC - numbers - A, N1, COUNT, A(I,J)
STRING -characters - A$, AS(I,]J)
LOGICAL - numbers or characters - A, A$, NOT B
Numeric variables will be integers, fractions, real and imaginary
numbers.
Strings will be names, characters and symbols.
Logical variables will be the values TRUE or FALSE, 1 or 0 as
appropriate to their use. Logic is dealt with in Section R.
We also require to know whether our data is:
INPUT
OUTPUT
or INTERMEDIATE
Intermediate data is used in the body of the program, e.g. the value of
a loop counter, or the intermediate result of a calculation. Intermediate
data is useful for testing and debugging purposes when running the
program or algorithm, using machine or hand traces.
The equations, functions and expressions that will use the variables
will need to be known. When dealing with equations, functions and
expressions the units of the variables or parameters concerned must be
known and should be stated.
The first and simplest data table to construct is a descriptive list of
variables to be used in the program. This is important for
documentation purposes. For example:
VARIABLE DESCRIPTION ITPR
A First number Input
B Second number Input
SUM Sum of A and B Output
A$ User response to Input
‘RUN AGAIN?’
For program design purposes the value ascribed to each variable at
different points through the programs can be added. This forms a data
table that is useful for checking the algorithm before and after coding it
into BASIC, and is also a way of analysing errors in your own
program, and understanding how other programs work.
71
ALGORITHM VARIABLES
MODULE N
N. 1
Loop counters are included in the list of variables. If their values are
used for calculation inside the loop, this should be stated. There are
some examples of this type of data table in the text.
REFINING THE ALGORITHM
The tree diagram should be further broken down and refined until the
final sub-modules correspond to recognisable BASIC statements and
structures. As you get more experienced, you will recognise more
complex structures, and the solution to a problem wil become
apparent at an earlier stage.
G7: Describe the Algorithm
1.4.1 WRITE OUT YOUR METHOD OF SOLVING
THE PROBLEM (THE ALGORITHM) IN STEPS
ІМ А SIMPLE ENGLISH STYLE
(PSEUDOCODE).
1.4.2 DRAW A FLOWCHART SHOWING HOW THE
PROGRAM WILL RUN FROM START TO
FINISH.
1.4.3 TEST THAT THE ALGORITHM WILL WORK
BEFORE CODING IT INTO BASIC.
Having broken our problem down into distinct things to do, or
subproblems, to a stage where we are able to write a BASIC program,
we need to do at least two things before we code. These enable us to
write programs that work and that other users can understand.
The algorithm description in pseudocode or flowchart form is an
important point of the documentation of your programs. This is not
written as part of the program but as a separate document which will
also include a listing of the program. This is important for other
programmers who may want to modify your program or use it as part
of a larger program, and for you yourself if you come back to it after a
72
period of time and cannot remember how you designed it! The
program listing alone is often not enough, if the algorithm is complex,
to show how the program works.
G8: The Pseudocode Description
In the structure or tree diagram - which we draw out in rough on a
piece of paper as we design our solution — each block or module right
down to the lowest level has an English description of the task to be
done inside it. (The very lowest level tasks will be described in
sentences that are very similar to the BASIC program statements
themselves, as you will see in Programming Methods II.)
Our algorithm will be written out, in a step-by-step fashion, and will
include all the descriptions in the boxes. The highest or first level
description (simple box) will be the algorithm and program title. The
second level will be the titles of the program sections. Each of these
major sections will encompass a further group of modules, all of which
will be named in our description of the solution.
The lowest level of our tree diagram will be the specific instuctions
the computer has to perform. These will be translated into the BASIC
language on an almost one to one basis, and will contain the important
and easily recognised language structures, for making decisions,
branching and jumping, and repetition that we have previously
mentioned. (A summary of pseudocode descriptions of some control
structures and their flowcharts with BASIC program equivalents is
given in Section 0, Programming Methods II.) If you imagine turning
the tree diagram on its side and taking away the boxes, the descriptions
that are left constitute a pseudocode description of the algorithm.
As an example, let’s look at the tree diagram and the algorithm
description for the problem of asking our robot to make a pot of tea.
Using our tree diagram we can write down our algorithm for making
a pot of tea as a sequence of instructions (to be coded later into a
computer language). We use the English language as our pseudocode
and our program is written directly from the sub-tasks in the bottom
line of boxes in the tree diagram.
We use the boxes at higher levels in the tree to define distinct
modules. Comments or REMARK statements identify each module
and explain what is being done in each algorithm section:
Remark * * Algorithm for robot to make pot of tea * *
Remark * Boil water - task 1.1*
1,4,4 ЕШ the Кеше with water
1,1-4 Walt until the water is boiling
1.3 Plug in the kettle and turn it on
Remark * End of task 1.1*
Remark* Module - Put tea in the pot — task 1.2 *
Ix Get toe pot
1.2.2 Put 200 tea bags in the pot
73
Remark” Епа of task 1,2%
Remark * Module - Put water in the pot - task 1.3 *
1,2,1 Take pot to kettle
1,2,2 Stir tea with spoon
1.54 Put lid on tea pot
Remark * End of task 1.3 *
Remark * * End of Algorithm - tea is made * *
You can see that the tree diagram shows why each part of your
algorithm is included and why it is in the particular position in which
you have placed it on the tree.
The tree diagram contains information about three things:
(1) The problem broken down into different levels of detail starting
from the general concept of what is to be done down to the
specific activities and instructions which will enable the problem
to be coded.
(2) ‘The order in which instructions must be performed.
(3) The comments which must be included to explain what the
program is doing.
Exercises
1 Our algorithm has the following mistakes in it:
a) Some instructions are wrong. They are spelt incorrectly
and the robot will not be able to recognise them.
b) Some instructions are in the wrong order.
c) Some instructions are missing in the algorithm.
d) Some instructions are missing on the tree diagram.
Find the mistakes!
2 Correct the tree diagram and the algorithm.
3 Expand the tree diagram and the algorithm to a further sub-task
level. For example:
„л Fill the kettle
becomes
1.1.1.1 Put kettle under tap
1.1.1.2 ‘Turn on tap
etc.
4 Draw а tree diagram and write the algorithm in pseudocode for
a robot to set up and switch on your microcomputer system.
G9: Flowcharts
Flowcharts are a second graphical method used in designing programs.
They consist of linked boxes of different shapes. Each shape has a
different use and, as with tree diagrams, each contains a brief
description of what the program should do at a particular point.
It is harder to design programs using flowcharts than with tree
74
diagrams. Their power comes from using them to help make visible
and describe the flow of control in the algorithm and the resulting
program. They are used to help code the program into BASIC
instructions, and later form an important part of the
DOCUMENTATION оға program. Note that flowcharts express the
important control structures used in programming in diagram form.
We give a selection of standard flowchart symbols here. There are
additional ones, but their usage varies. The conventions of use should
be followed if you wish other people to understand your flowcharts. For
your own use, in analysing programs, you may be less exact, but not
less systematic. Flow in a program can be illustrated by a selection of
blobs and rectangles only, given that the lines of flow are correctly
given, and the right words are written in the blobs! Doing this is all
right for yourself, but not if your flowcharts are to be comprehensible to
others.
FLOWCHART SYMBOLS
Flow lines. These connect the program blocks.
Y “pes The arrows show the direction of flow, and are
very important.
This symbol represents any kind of processing
function, that is general Programming
dinis Statements, i.e. ''Purchase Tea'' or
LET A- В + С.
This represents а decision, with а Conditional
— test, e.g. “Is there another shop open” or
<> IF A=3 THEN ... It has a Yes/No branch,
No according to whether the condition is True or
False, which determines the program flow.
This represents either Output in the program
m" to the screen or printer, or Input from the
keyboard, e.g. PRINT “HAVE YOU A
PACKET OF TEA?” or INPUT B.
This represents a named process that is
specified elsewhere, e.g. Subroutine GOSUB
1000. The subroutine would have a separate
flowchart.
75
This represents an exit to or entry from another
part of the flowchart, allowing one part of the
chart to be connected to another part. Used
when another direct line link would be
confusing, or to connect to a separate page.
This represents the Crossing of two Flow
Lines. They are not connected.
This represents the Junction of Flow Lines.
The two lines of flow join.
STOP Terminal Point, e.g. Start, Stop, Pause.
A flowchart does not branch out like a tree diagram. It always
converges to the stop point. It has a direct relationship to the program
it describes. Writing down a flowchart is rather like drawing a diagram
of the program itself. Below are some examples of simple flow
structures, with the program and the flowchart.
FLOWCHART PROGRAM
1. Simple sequences
10 LET X = 5
20 INPUT Y
30 PRINT X,Y
FLOWCHART PROGRAM
2. Decision and program branch
40 IF Y-0 THEN GOTO 70
50 LET X=100
60 GOTO 80
70 LET Х-0
80 PRINT X
90 STOP
Notice that we have omitted a flowchart symbol for line 60. This
GOTO is indicated by the flow lines. The same is true of the GOTO in
the conditional statement of line 40.
10 INPUT X
20 IF X-0 THEN GOTO 50
30 PRINT X
40 GOTO 10
50 REM **END**
PRINT X
77 :
Notice that the above flowcharts represent the programs line by line.
Flowcharts can also be less detailed, and the flowchart symbols used to
represent program blocks (sequences of program instructions) or
modules rather than one or two lines. They then describe a less detailed
flow structure. We might have a flow that was represented like this:
INSTRUCTIONS
INPUT
10
NUMBERS
FIND SUM,
AVERAGE
This is like a flowchart of a higher (less specific) level of a tree diagram.
Each section could have a more detailed flowchart drawn up to show
the individual lines of the program, or comments could be added to the
blocks above, relating the program lines to the blocks:
78
INPUT Input loop in lines
10 а Г
40 t
NUMBERS o 69
You will soon start to write short programs, and should draw up
flowcharts with each program line or instruction indicated separately.
Later, for longer programs with large numbers of lines, the flowcharts
must be condensed where the sequence is simple to follow in the program, to
keep them of manageable size. Any complex manipulations should still
be included in full.
EXAMPLES
(1) Here is a flowchart for our robot. We are going to ask it to buy a
packet of tea.
ENTER
SHOP
HAVE
YOU A PACKET
OF TEA
LS
THERE ANOTHER
SHOP
PURCHASE
TEA
79
In the same way as our ‘making a pot of tea’ problem which the robot
has to solve, each of these boxes must be broken down into simpler
instructions. On a simple flowchart it may not be possible to see how
the problem has been broken down. What we must do is either draw
the whole flowchart again with more detail or draw new expanded
flowcharts at specific points, e.g. “ENTER SHOP” could be replaced
with the following:
80
(2 Here is a flowchart of a program to input two numbers, output
the sum, and ask you if you want to run the program again.
81
INPUT À
INPUT B
LETS = A+B
PRINT S
PRINT ‘‘RUN AGAIN?
(ҮЕ5/МО)”
INPUT A$
IF A$ = ‘‘YES’’ THEN
GOTO 10
STOP
AN EXAMPLE OF STRUCTURED DESIGN
Problem: Find the average of five numbers:
(1) TREE DIAGRAM
Find Average
of 5 numbers
Get each
Set counter number, add Find Print
& sum to Q it to the sum Average Average
Let Sum =
Let Counter
Add 1 Input
to counter number
End of
summing if
counter = 5
Let Let If Counter Let Print
Counter = Sum = = 5 then Average Average
Counter +łŁ Sum+X end summing =Sum/5
(2) FLOWCHART
START
SET
COUNTER
-0
92
ADD
COUNTER
Note that the flowchart and program test whether the counter value is
less than 5, using the < symbol.
(3) PROGRAM
REM “AVERAGE”
REM ** PROGRAM FINDS AVERAGE OF FIVE
NUMBERS INPUT **
REM ** START **
LET SUM = 0
LET COUNTER = @
LET COUNTER = COUNTER + 1
INPUT X
LET SUM = SUM + X
IF COUNTER < 5 THEN GOTO 60
83
100 LET AVERAGE = SUM/5
110 PRINT AVERAGE
120 KEM ** END **
The operand “” means ‘divided by’ and is equivalent to the ‘+’
symbol.
Exercises
1 Design an algorithm (using tree diagram) and write a BASIC
program with a flowchart to find the sum and average of ten
numbers to be input at the keyboard.
2 Produce the tree diagram, flowchart and program which
calculates the area of any rectangle.
3 Design the algorithm, BASIC program and flowchart which
calculates the total volume and weight of three boxes to be
airfreighted from London to New York. Use the following data:
BOX LENGTHCM BREADTHCM HEIGHTCM WEIGHT KG
1 20 4 2 2
2 40 3 6 2.5
3 70 10 15 20
Test that it works!
G10: Testing the Algorithm
It is always best to make sure your method of solving the problem
actually works before coding it into BASIC. This pre-coding check is
known in the programming trade as a DRY RUN or WALK
THROUGH.
Using the DATA TABLE, we check through, module by module,
the values of all the variables, expressions and counters step by step
through the algorithm. This will uncover errors in the logic and
method and will save time when debugging the finished product later
on. Professional programmers always do this as they have to work to
very tight time schedules, and by doing things properly at the start they
save time later on. We would like you to try a few walk throughs on the
simple programs you will be designing at first, just to get the hang of
the idea.
We have now covered the first essential steps in designing a program
and have seen a simple coding process. We have talked about methods
and concepts and introduced some new terminology. After concepts we
go to detail.
The algorithm is ready to be coded into a BASIC program. In doing
this we are going to put into the program the fundamental
programming tools, which are language structure and control
structures. We have to know what these structures or tools are before
we can use them. This requires a look at how Sinclair BASIC, through
small groups of instructions, enables decisions to be taken, branching
94
and jumping to different parts of the program to happen, repetition of
parts of the program to take place and how separate modules called
subroutines and sub-programs can be called into action where
necessary — these are the language structures.
Let’s go and meet them!
85
SECTION H: CONTROL
H1: Control in Programs
The statements which make up a BASIC program are numbered.
BASIC is thus called a LINE NUMBERED LANGUAGE. Control in
all BASIC programs is carried out by reference to these line or
statement numbers. The ZX81 and Spectrum will normally run a
program from the lowest numbered statement through to that with the
highest number unless instructed to do otherwise. This is exactly what
concerns us here, and thus we need to recognise that we can control the
order in which program statements are executed by using four
important instructions in Sinclair BASIC:
- GOTO (for direct transfer)
- IF-T HEN (for decisions and
branching)
- FOR-NEXT (for loops
(repetitions))
- GOSUB-RETURN (for
accessing program modules
called subroutines)
These instructions are used singly or combined together with other
instructions to form groups of program statements called CONTROL
STRUCTURES. There are four principal control structures:
- DECISION AND BRANCH
- LOOPS
- SUBROUTINES
- NESTED STRUCTURES
In this Section we will discover how to take decisions and branch to
other parts of the program. We will study the remaining structures
later in Part Three. The most important property of a computer is that
it can be programmed to make decisions, by using the relational or
conditional operators of BASIC.
H2: Condition Testing
CONDITIONAL OPERATORS
Conditional operators are also called relational operators as
they determine the logical relationship between two
expressions, numeric or string, as:
Equality: =
Inequality: «<>
Greater than: >
Less than: <
Greater than or equal to: >=
Less than or equal to: <
The priority of conditional operators is 5. Priority will be
explained in Section J.
They are executed in order left to right across a statement
unless in brackets.
We often need to use the complements or opposites of these operators
in decision making. The complements are:
Operator Complement
equality = inequality <>
greater than > less than or equal to < =
greater than or equal to > = less than <
The reverse operations are true in each case.
H3: IF-THEN
IF-THEN
Conditional operators are used with:
IF-THEN statements
IF (CONDITION IS TRUE) THEN (PERFORM AN
INSTRUCTION).
For example: 40 IF (А = B) THEN GOTO 10
50 IF C <=6 THEN STOP
60 IF J > K THEN PRINT “J”
The format of the statement is:
IF (CONDITION) THEN (INSTRUCTION)
Any BASIC instructions can be used in this kind of statement,
although a number are unlikely to be useful (e.g. NEW, CLEAR).
In general if the condition in the program line is TRUE then the
instruction following the condition is obeyed. If the condition is not
TRUE (FALSE) then control passes to the next line.
This powerful facility enables us to branch and transfer control to
another line in the program.
IS YES BRANCH
THE CONDITION
(TRUE PATH)
TRUE?
NO BRANCH (FALSE PATH)
GO TO THE NEXT LINE
87
H4: GOTO [Instructions
GOTO
The normal control sequence in a program is via numbered
statements — from the lowest to the highest. GOTO (line
number) switches control to the line number specified:
100 GOTO 20
200 GOTO (B + C)
As a command GOTO 30 executes a program from line 30.
Unlike RUN, with this method variables are not cleared
before execution.
The Spectrum includes a space between GO and TO when printing
this instruction.
Exercises
Key in and run this program which checks that only positive numbers
are input and gives a bad data error message as well as prompting for
the next input. Notice the use of IF-THEN and GOTO. INPUT both
positive and negative numbers.
10 REM*INPUT CHECK*
20 INPUT A
30 IF A»0 THEN PRINT A
40 IF A«-0 THEN PRINT "BAD IN
PUT"
50 PRINT "HAVE YOU ANOTHER NUMB
ER? ANSWER YES OR NO"
60 INPUT AŠ
70 IF А5 ="YES"THEN GOTO 20
88 STOP
90 REM*END INPUT CHECK*
Now try these exercises which demonstrate the power of GOTO:
1 10 PRINT “CENTURY”;
20 GOTO 10
Run this program
2 10 GOTO 80
20 PRINT “COMPUTERS'”';
30 GOTO 10
40 PRINT ‘‘PERSONAL”’;
50 GOTO 20
88
60 PRINT ''SINCLAIR'';
70 GOTO 40
80 GOTO 60
Key it in and sort it out!
This is called ‘spaghetti programming’. Structured programming
techniques have been designed to avoid the excessive use of GOTO
statements.
3 10 INPUT A$
20 PRINT A$;
30 GOTO 10
INPUT some graphics characters
and watch the patterns!
4 Кеуіп and run this example:
10 INPUT A
20 IFA = 1 THEN FORI = 1 TO 10
30 PRINT “CENTURY”
40 IF A=1 THEN NEXT I
50 STOP
Line 10 asks you to input a number.
Line 20 examines if it is equal to 1. IF this condition is TRUE then a
FOR-NEXT loop is set up to print “CENTURY” ten times. If it is not
TRUE then control passes to the next line.
Line 30 “СЕМТГКҮ” is printed once.
Line 40 the condition is tested again. If TRUE the loop continues
and CENTURY is printed again. If not then control passes to line 50.
Line 50 stops program execution.
Can you understand it? If not wait until you have read the section on
LOOPS.
H5: Decision Structures
DOUBLE DECISIONS
The simplest decision involves the evaluation of a LOGICAL
CONDITION - i.e. a condition that may have the value of either
TRUE or FALSE. A result of this evaluation decides which part of a
program is executed next. These parts of the program are called
TRUE TASK and FALSE TASK.
89
The flowchart for the Double Decision STRUCTURE is:
It is called a double decision as there are two alternative modules that
can be performed.
In the flowchart, if the indicated condition 1s true, then the program
section representing the True task is carried out, otherwise the
program section representing the False task is performed. Only one of
the paths from the condition test is taken, and the program will
continue at the statement represented by the arrow at the bottom of the
flowchart.
Each task can be a single instruction or a statement or a group of
instructions.
The Double Decision Structure is known by the general name of the
"IF-THEN-ELSE Decision Structure’’. Its general form 1s:
IF (condition) THEN (true) ELSE (false)
This means: IF the condition tested is True THEN perform the True
task, and IF the condition is not true perform the False task.
Our algorithm description of it would look like:
1. Decision Module.
1.1 Do the test. If result is True then
1.22 По True task
1.3 Otherwise do False task
We can write this formally in pseudocode as:
90
module - decision
if condition
then True Task
else False Task
end if
end module
End if and end module are bounds to the structure. In Sinclair BASIC
we code it as:
10 IF (cond) THEN (branch to True task)
20 (False task)
Note that in this case the only literal equivalent of BASIC from the
pseudocode is with the use of IF and THEN.
The branch to the true task is made with a GOTO instruction. For
example:
10 IF A»0 THEN GOTO 100
20 REM * FALSE TASK *
ЗӨ uus
90 GOTO 120
100 REM * TRUE TASK *
110 PRINT A
If we did not branch to the true task starting at 100 and used:
10 IF A20 THEN PRINT A
20 REM FALSE TASK
in line 10, the true task would be processed and control would then
pass to line 20 - the false task. In other words, both tasks would be
processed! Watch out for this.
EXAMPLE: Input two names as strings. The program compares
them and prints them out in alphabetical order:
91
14 REM * ALPHA *
20 INPUT A$
30 INPUT B$
40 IF A$<B$ THEN GOTO 80
FALSE 50 PRINT B$
TASK 60 PRINT A$
70 GOTO 100
TRUE 80 PRINT A$
TASK 90 PRINT B$
100 STOP
110 REM * END ALPHA *
THE SINGLE DECISION
This is a special case of the double decision structure in which there is
only one task to perform - the True task.
TRUE
TRUE
TASK
This is called an IF-THEN decision structure. Its BASIC form is:
IF (Condition) THEN (True)
Which means:
IF (the condition test is true) THEN (perform the true task)
Our algorithm description would be:
1. Decision module
1.1 Perform test
1.2 If True, process true task
92
A brief formal pseudocode description is:
mod - Decision
if Condition
Then P
end if
end mod
Our BASIC statement is:
IF (condition) THEN (TRUE)
EXAMPLE: Input numbers and stop if a number greater than 10 is
input:
10 INPUT A
20 IF A>10 THEN STOP
30 GOTO 10
5ТОР
Note the abbreviation of True to Т апа False to F.
MULTIPLE DECISIONS
There is often the need in programs to perform several tasks based on
the result of a set of conditions. To solve these problems we use a
93
multiple decision structure. This kind of structure is especially useful in
breaking up larger tasks into smaller ones.
Multiple decisions are most conveniently handled by multiple logical
operations. This is covered in Section R. We will consider the
conventional way of handling them.
As an example of multiple decisions consider a food vending
machine. You put a coin in and press the respective button of the
article you wish to be delivered to you. Another example would be a set
of arithmetic testing programs, with questions in each. The computer
would ask you which set of tests you required, you would key in the
reply and, from several alternatives, the required program would run.
The flowchart for such a structure is:
START
Where C1, C2, C3 are the conditions and Р1, Р2, P3 are the True
tasks.
EXAMPLE: Input any of three letters A, B, C and print out a
corresponding reply.
= FRINT "ENTER AoE üR C"
10 INFUT ñ$
20 IF АФ-"А" THEN GOTO 60
94
30 IF А%Ф-"Е" THEN GOTO ЕО
40 IF AS="C" THEN GOTO 100
20 STOP
60 PRINT “YOU INFUT A"
70 STOP
S0 FRINT “YOU INPUT Е"
90 STOP
100 PRINT “YOU INPUT C"
110 STOF
The Pseudocode description of this structure is:
case
if Cl
then P1 10 IF (C1) THEN (P1)
if C2
then P2 20 IF (C2) THEN (P2)
if C3
then P3 30 IF (C3) THEN (P3)
endcase
endmod
PROGRAMMING WITH GOTO
When programming in BASIC take great care in how you use the
GOTO statement. It takes two main forms. Used on its own it 1s called
an unconditional GOTO and when used with IF-T'HEN it is called a
conditional GOTO.
GOTO enables you to jump around in a program like a flea on a
blanket - don't do it! Try and code your program to execute in
sequence and avoid it becoming a bowl of spaghetti. Excessive use of
GOTO makes programs difficult to refine and debug. Relationships
between the program paths become difficult to follow. However — do
not take the other extreme and write awkward complicated code to try
and avoid GOTOSs!
Ideally, unconditional GOTO statements should only be used to
skip over code and not to repeat code sections (i.e. they should only be
used to transfer control forward in a program).
Do not put an unconditional GOTO inside a loop or subroutine to
jump out of it. Do not jump inside a loop or subroutine, because you'll
find that jumping in and out of loops can cause unpredictable results.
Do not jump to another GOTO. For example:
100 GOTO 200
200 GOTO 300
95
or else
100 GOTO 100 !
Exercises
1
2
H6: L
Write a program to input integer numbers and stop if zero is
input.
Write a program to input integers and count the number of
times zero 15 input.
Write a program to input integers and calculate the percentage
of zeros input.
Write a program which prints out the result of dividing any two
numbers’ input and gives a “Һай data - try again” message if
any of the input values is zero.
Write a program which will print out on request a lunch menu
for the different days of the week.
ogical Operators: AND/OR
We will only introduce you to simple logical operations here. Logic is
dealt with fully in Section R.
Use
of the AND and OR statements enables us to combine
conditional statements in powerful ways to make more complex
decisio
ns in programs.
AND
AND combines relations so that the expression:
e.g.
(condition 1) AND (condition 2)
(A = B) AND (В>1)
is TRUE when BOTH conditions are TRUE.
It is FALSE when one or both conditions are FALSE.
OR
e.g.
OR
combines relations so that the expression:
(condition 1) OR (condition 2)
(A = B) OR (B<>1)
is TRUE when EITHER condition is TRUE.
It is FALSE when both conditions are FALSE.
The expressions formed by the use of AND and OR are used with
LE ua d.
HEN statements. For example:
20 IF Х>1 AND X«10 THEN PRINT
'* BETWEEN 1 AND 10”
96
50 IFX<>2 AND X<>3 THEN PRINT
< A МОТ EQUAL TO 2 ОҚ”
40 IF A=B OR B=C THEN LET F=F+1
The first example will be true if X is greater than 1 and X is also less
than 10, and the message will be printed. If X was 11, the first
condition would be true, but the second false. The whole expression
would then be false.
Notice the danger with the second example, in that we say in English
‘not equal to 2 or 3’, but we must key in an expression using AND. It is
clear once you realise that two conditions are to be tested — ‘not equal
to 2 and not equal to 3’. If, for example, X were 3 when this line in the
program was reached, then the second condition would be false in this
expression, and the whole expression would also be false.
The third example would be true if ezther A was equal to B or if B was
equal to C. It is also true if both these conditions are true.
We can also combine more than two conditions:
20 IF A=BANDB=CANDC = 20 THEN STOP
will stop if all three conditions are true. If one or more is false then the
whole expression is false.
Similarly:
20IFB-20R B-3ORB-4THEN LET B- 1
will make B - 1 if B is equal to 2 or 3 or 4.
It is also possible to use combinations of AND and OR:
30 IF (A = BAND B>2) ОК (A = 2 AND B = 3) THEN GOTO 60
The expressions in brackets are evaluated first. The first expression in
brackets will be true if B is greater than 2 and equal to A. The second
expression will be true if A is 2 and B is 3. The program will pass
control to line 60 if either expression in brackets is true.
To summarise: where T1, T2 etc. are true conditional expressions
and F1, F2 etc. are false conditional expressions:
(T1) AND (T2) TRUE
(T1) AND (F2) FALSE
(F1) AND (T2) FALSE
(F1) AND (F2) FALSE
(T1) OR (T2) TRUE
(F1) OR (T2) TRUE
(T1) OR (F2) TRUE
(F1) OR (F2) FALSE
Each condition may also be another AND or OR expression.
Exercises
Work out what will be printed by these programs, then key in and run
them to check. The operator ‘‘/’’ means ‘‘divided Бу” (+) and “%”
means ''multiplied Бу” (*).
97
Make sure you have got the programs correct before you run
them. Work out both sides of each expression using a relational
Then, giving each expression a T or F value, work
out the bracketed AND/OR expressions. This gives you a T or F
value for the whole bracket. Then work out whether the whole
operator first.
LET A=2
LET B=3
LET С-10
LET X=15
IF X/B=A AND C/A=5 THEN PRINT
"LINE 50 TRUE"
IF X/B-A OR C/A=5 THEN PRINT
"LINE 60 TRUE"
IF X/B=C/2 AND X>=15 THEN PRINT
"LINE 70 TRUE"
LET A-20
LET В-150
LET X=7.5
LET Y-2
LET 5-В/20
IF S=X AND X*A-B AND Y-2 THEN
PRINT "LINE 60 TRUE"
IF X-B OR X«20 OR X>2 THEN
PRINT "LINE 70 TRUE"
IF (X=7.5 OR Ү-10) AND (A/Y-1
@ AND В-150) THEN PRINT "LINE
80 TRUE"
expression will be true or false.
Write some similar programs for yourself to experiment with all
the relational
operators used with AND and OR.
98
SECTION I: PRINTING
I1: PRINT LPRINT
PRINT
The PRINT statement is used to output information by
displaying it on the screen.
It can take many forms. For example:
10 PRINT A prints out the value of
numeric variable A
20 PRINT B$ prints out string variable B$
30 PRINT “YOUR NAME?" prints out whatever is
included within the quotes
(inverted commas)
40 PRINT (B**2 — 4*A*C) prints out the calculated
value of the expression
50 PRINT leaves a blank line
LPRINT
The LPRINT statement is used to output information by
printing it out on the printer.
The LPRINT statement is used in exactly the same way as the PRINT
statement, but produces printer and not screen output. If the printer is
not attached LPRINT statements are ignored.
The screen size for printing is 22 PRINT lines down the
screen, and each line is 32 columns (character spaces) wide.
The actual screen size is 24 lines by 32 columns, but the
bottom two lines are reserved for commands and operating
messages. The lines are numbered @ to 21 down the screen
and the columns 0 to 31 across.
The PRINT statements shown above each commence at the left-hand
side of the screen, and each PRINT statement moves the printing
position to the start of the next line after it prints whatever it was told
to. Lines of greater than 32 characters will go on to the next line
automatically.
To clear the screen of printing we use the CLS (Clear Screen)
statement.
99
CLS
CLS erases all printing on the screen, and sets the new print
position at the start of the top line of the screen.
I2: Spacing Items on the Screen
Е
А semicolon (;) between two items causes the printing of the
second item immediately after the first.
For example:
10 PRINT A;B$
20 PRINT “АУЕКАСЕ”;С
Try the following program:
10 LET A=6.89
20 LET B=87.6
30 PRINT A;B
40 PRINT ''AVERAGE"'';(A + B)/2
The display is:
6.8987.6
АУЕКАСЕ47.245
This does not give а very satisfactory display since values run into each
other. One simple way to overcome this is shown below.
10 LET A= 6.89
20 LET B=87.6
30 PRINT A;" "В
40 PRINT “AVERAGE ”;(А+В)/2
The display now becomes:
6.89 87.6
AVERAGE 47.245
ci
A comma (,) between two items causes the print position to be
shifted on (at least one place) to either column 16 or to the
next line column 0.
For example:
10 PRINT A,B
20 PRINT A$,B$
30 PRINT “АУЕКАСЕ”,С
Try the following program:
10 LET A= 7.65
20 LET B= 8.67
30 PRINT “AVERAGE” (А + B)/2
100
40 PRINT
50 PRINT ‘‘NUMBER!1’’,‘‘NUMBER2’’,
“АУЕКАСЕ”
60 PRINT A,B,(A + B)/2
The display is:
AVERAGE 8.16
МІ/МВЕК1 NUMBER2
AVERAGE
7.65 8.67
8.16
Clearly the comma is useful if we wish to print a table with two
columns, but is unsuitable if we wish to have a table with more than
two columns.
It is important to remember the screen size when deciding the
form of your output. For your output the effective screen is 22
lines each 32 columns wide.
TAB
TAB C; moves the print position to column C. If this would
involve back-spacing it moves on to the next line.
The following program (with printout) indicates how the TAB function
can be used to improve the presentation of results.
10 LET А$ = “А.В.ЈОМЕЅ”
20 LET B= 65
30 PRINT “NAME”;TAB 6;A$; TAB 19:“АСЕ”:
TAB 23;B;TAB 27; “YEARS”
NAME A.B.JONES AGE 65 YEARS
Note the semi-colons between TABs and print items. It is important to
remember that each line has 32 columns, numbered 0 to 31.
The next program shows a simple way of tabulating results.
10 PRINT “МО.”;ТАВ 4;“5ОСАКЕ”;ТАВ 12;
“СІУВЕ”;ТАВ 20;*RECIP"
20 INPUT N
30 PRINT N;TAB 4;N*N;TAB 12;N*N*N;
TAB 20;1/N
40 GOTO 20
101
NO. SOUARE CUBE RECIP
1 1 1 1
2 4 8 0.5
3 9 9/ 033333333
4 16 64 0.25
5 25 125 0.2
6 36 216 @.16666667
7 49 242 0.14285714
8 64 512 0.125
9 81 729 0.11111111
10 100 1000 0.1
It is important to remember that numbers are output with up to 8
figures and allow the appropriate space. An alternative is to decide how
many figures you want and use the INT function (see Section J).
I3: PRINT AT
AT L, C moves the print position to line L and column C.
For example:
10 PRINT AT 10,12“ CENTRE"
will cause the string specified to be printed starting at line 10, column
12, i.e. roughly in the centre of the screen - since L goes from 0 to 21,
counting down the screen, and C goes from 0 to 31, counting left to
right.
EXAMPLE
The program below sets up a symmetrical pattern using the character
of your choice. Note the use of the command CLS to clear the screen of
your input.
10 PRINT AT 5,4;"WHICH CHARACTER?"
20 INPUT AŠ
30 CLS
40 LET L=INT (RND*10)+1
50 LET C=INT (RND*15)+1
60 PRINT AT 11%,,164С;А65
70 PRINT АТ 11-L,16-C;A$
80 PRINT AT 114L,16-C;A$
90 PRINT AT 11-L,16+C;A$
100 GOTO 20
Try adjusting the parameters in lines 60-100.
The important feature to remember is:
Number of character cells is 32 horizontally by 22 vertically,
i.e. 32 x 22 altogether.
The TAB function uses C = @ to 31 only.
The AT function uses L = 0 to 21
and C = 0 to 31.
You should have noticed that the PRINT commands reinforce each
other, and provide alternative ways of achieving the aim of placing
characters, character strings or numbers at the desired positions on the
22 line, 32 column screen display.
For example, these three programs:
19 LET X = 3
20 PRINT X,,;,
30 PRINT X*X
10 LET X = 3
20 PRINT X
30 PRINT
40 PRINT X*X
10 LET X= 3
20 PRINT X,TAB 32;" "TAB 32;X*X
would give the same printout on screen. The number of keystrokes
(count them) is what determines which statement usage is efficient in
any instance. You will soon come to recognise which to use if you
experiment.
PRINT AT instructions will overprint anything already printed at
the position specified. We can use this to replace on the screen one set
of data, or one string, by another.
10 INPUT X
20 PRINT AT 0,0;X
30 GOTO 10
overprints one X by the next X each time. If we input 1,2,3...10 it
works fine. But if we input 10,9,8...1 we get:
etc.
Similarly,
ZU ЕТТІ”
40 PRINT AT 10, 10; “SINCLAIR”
works, but not if we swap the two strings around - we end up with
ZX81LAIR, and we have the same problem with numbers, which can
be between one and eight digits long.
We can blank out something on the screen by overprinting an empty
string. For the simple problems above, the addition of appropriate
103
strings will work; we add 4 spaces after “27Х81”, so that line 10
becomes:
10 PRINT AT 10,10; “ZX81 E
and for numbers, we can use:
20 PRINT AT 0,0;X; *“ id (7 spaces)
Using LPRINT also requires care.
For the LPRINT instruction, TAB works exactly as PRINT
TAB.
LPRINT AT L,C is converted to LPRINT TAB C, and the
line number is ignored.
This is because the printer cannot go back to a previous line. Try this
program. Input 1,2,3,4,5.
10 INPUT X
20 LPRINT AT X,X;X
30 GOTO 10
will print 12345, as if line 20 had read LPRINT TAB X;X.
For any programmed screen format that 1s not a simple sequence of
print lines, it is better to use COPY to produce output on the printer,
once all the data is on the screen.
COPY prints the entire current screen display on the printer.
If used as direct command, we can COPY less than a whole screen by
pressing BREAK before completion, but if used in a program, the
whole screen will be copied.
14: The Graphics Characters оп the ZX81*
The ZX81 character set includes a set of graphics characters, and you
were told how to access them in Section B. To recap:
Graphics characters are accessed by using |Graphics| to get
the cursor. Repeat to return to cursor. Unshifted keys
then produce inverse video characters. (e.g. key Q gives |.)
Shifted keys produce graphics cells, if shown on the keys: e.g.
SHIFT R gives "W .If no graphics cell is shown, result is
inverse video form of normal shifted character (e.g. SHIFT U
gives В ).
The inverse video characters and graphics cells can be used for
enhancing displays and drawing bar charts, diagrams and pictures.
They are manipulated as strings, by putting quotes round them, e.g.
PRINT “ ER or PRINT “ B”.
* The Spectrum offers more extensive graphics facilities than the ZX81, and Spectrum
owners should refer to Unit W3 for details. The Spectrum has the solid graphics
characters of the ZX81, but not the shaded characters, on keys 1 to 8 in graphics mode.
Read through this section bearing this in mind.
104
Put your computer in graphics mode and run through the keyboard,
noting the unshifted and shifted versions of each key. Note that
RUBOUT (DELETE) works with the cursor, but the cursor
control keys do not, and that the cursor must be on screen for them
to work.
By the time you fill one line and move on to the next, you will see
that all these graphics characters Join up, with no gaps between the
cells. The difference between the grey cells on the A and K keys is that
they Join up with the half-shaded graphics cells on the S, D, F and G
keys in different ways. Experiment with these. If they join up properly,
you cannot see the Join. If they do not, the Join is visible as a chequered
pattern. To check the characters across the screen, use the bottom lines
of the screen directly. To check the vertical Joins, enter this program:
10 INPUT A$
20 PRINT A$
30 GOTO 10
Change the cursor to [G], then input the graphics character. You
have to then press NEWLINE (ENTER) twice; the first time to change
to [L], the second to input the character.
We can use the graphics characters to draw (crude!) pictures,
enhance printout on the screen — by printing prompts in inverse video
for example —or putting titles inside surrounds, and use them in
diagrams or moving graphics. You'll have to wait a few more chapters
before we can do anything interesting, but here are a few things to try:
Here’s a program to put a border round a word in inverse video.
Notice we store the graphics in string variables. This gives us better
manipulative power than if we just used literal strings. On the ZX81
the graphics characters in A$ are the shift graphic on the E key, 11
times the one on the 7 key and the one on the R key. If you are using a
Spectrum, the relevant keys are ‘4’, ‘3’ and ‘7’. You can work the
other lines out for yourself.
A
s
ie
zu
зә
46 i
се
e
Notice the combined PRINT AT statements in line 60.
The production of inverse characters on the Spectrum (white
characters on a black background, unless colour is being used) can be
done in different ways. You can use CAPS SHIFT and the 4 key to put
an INVerse VIDEO control character before a letter or other
character, but this will make a// characters thereafter into their inverse
forms unless CAPS SHIFT and 3 is used to restore NORMAL
VIDEO. The alternative is to use INVERSE as part of a program
105
statement. INVERSE is obtained using SYMBOL SHIFT and the M
key in E mode. To get inverse video this must be followed by 1, so that
to print HELLO in inverse video we key in:
10 PRINT INVERSE 1; "HELLO"'
This will appear normally in the program listing, but in inverse when
the instruction is carried out.
Now add the following lines, and you will see why the use of string
variables, and variables for the line and column numbers, can be
useful.
70 LET X=X+1
80 LET Y=Y+1
90 CLS
100 GOTO 60
Run the program, and you see we have a crude moving display. CLS
makes the screen ‘flash’ a bit, but we could avoid this by overprinting.
Revise the program to erase by overprinting empty strings.
We can use the graphics characters for pictures. Try this:
10 PRINT AT 0,9; “аша ` _
20 PRINT AT 1,8; === =
30 PRINT AT 2,8; “ "EE"
(it’s supposed to be а car).
Change the program to allow you to input a value for Line and
Column numbers, so that you can place the car in different places.
Then add a GOTO loop to allow multiple cars on the screen.
Exercises
1 Write a program that puts:
ADDRESS:
on the screen, then prompts for inputs on line 20 (INPUT
NAME etc), and prints the responses on the screen.
Each prompt should overprint the previous one. Allow four
separate lines for the address. Blank out the last prompt, then
have the screen copied on the printer.
106
Add a routine to LPRINT name, address and age, without the
borders or titles, on the printer after deleting the COPY
Instruction.
Input names, ages and occupations of three friends and arrange
them to be tabulated in a suitable form.
Experiment with ways to make the car move across the screen.
107
SECTION J: ARITHMETIC AND FUNCTIONS
Ji: Arithmetic Operations
A prime function of the computer is to evaluate formulae and
expressions similar to those used in standard mathematical calculation.
Algebraic EXPRESSIONS are written in BASIC using the
following OPERATORS with a set of variables or numbers as the
OPERANDS.
ARITHMETIC OPERATOR EXAMPLE
SYMBOL NAME PRIORITY BASIC MATHS
in exponentiation 10 А**3 А?
(raising to a power)
[^1] (on the Spectrum) А13 A?
- negation 9 -А -А
и multiplication 8 A*B AxB (a.b)
/ division 8 A/B A+B e
+ addition 6 A+B A+B
_ subtraction 6 А-В А-В
Note that negation operates on one operand ~ a unary operation ( i.e.
makes a variable negative, e.g. — A) and that the subtraction operator
uses two operands, e.g. А-В, a binary operation.
J2: Priority
1 All arithmetic, conditional and logical operations are assigned a
priority number from 10 to 1. High priority is 10, low priority is
1. The priority numbers for the arithmetic operators are as
shown in the previous Unit.
2 The priority of an operation determines the order in which it is
evaluated in a complex statement in which more than one
operation is to be performed. High priority operations are
performed earlier.
3 Brackets (parentheses) are used in BASIC algebraic expressions.
Brackets clarify which expressions constitute separate values to
be operated on. Expressions inside brackets are evaluated first
before the quantity is used in further computation. With multiple
(nested) brackets the evaluation proceeds from the innermost
bracketed expression to the outermost.
4 For operations of equal priority in the same statement,
evaluation is from Left to Right.
Brackets can often be omitted when the sequence of evaluation is
108
understood, but there is no harm in using them to ensure correct
evaluation. Expressions may be tested by using PRINT as a direct
command, to check that you have them correct. For instance key in
PRINT (8*2.6/5)*2/3 and press NEWLINE (ENTER). The result will
be printed on the screen. If a sequence of direct assignments of values
to variables is keyed in first (using LET A = 4 (NEWLINE/ENTER),
LET B = 3 (NEWLINE/ENTER), etc.) then variable expressions may
be evaluated.
Using this facility you should experiment with a variety of
expressions until you feel confident that you have understood the way
in which expressions are evaluated, and the way you have to formulate
an expression in BASIC to ensure it returns the desired result.
EXAMPLES
1 Evaluation ofa+b-c
In BASIC: A+B-C
Operators have equal priority;
(1) Left to Right A+B
(2) L-*EK (A+B)-C
2 Evaluation of ab , (axb) +c
In BASIC A*B/C
* has same priority as /
H LR A*B
(2) L*R (A*B)/C
3 Evaluation of a.(2) ‚ах (b+c)
In BASIC A*(B/C)
(1) Brackets first (B/C)
(2 Multiplication — A*(B/C)
But notice we could write the expression without brackets in
BASIC as B/C*A
This is evaluated:
H LR (B/C)
(2) L= Е (B/C)*A
which gives the correct result.
4 Evaluation of (b° - 6c)*+5
In ZX81 BASIC notation: (B**2 = GG )**24 5
(1) Inside bracket;
exponentiation B**2
(2) Inside bracket;
multiplication 6*C
(3) Inside bracket;
subtraction (B**2) - (6*C)
109
(4)
(5)
Exponentiation ((B**2) - (6*C))**2
Addition (((B**2) – (6*C))**2) +5
In Spectrum BASIC notation: (B 2 - 6*C )#2+5
(1)
(2)
(3)
(4)
(9)
Inside bracket;
exponentiation Bez
Inside bracket; 6*C
multiplication
Inside bracket;
subtraction (В%2)-(6“С)
Exponentiation (В t 2). – (6*C))4 2
Addition (((B f 2) – (6*С)) # 2) +5
2
Computer evaluation of a.b- © + (e - f)
d g
In ZX81 BASIC notation: A*B - C**3/D +(E-F)/G
(1) brackets E-
(2) exponentiation Er
(3) multiplication/
division L — R А“В C'"3/D (Е-ЕУС
(4) addition/
subtraction L > R (A*B) - (C**3/D) + (Е – Е)/С
In Spectrum BASIC notation: А*В - С \ 3/0 +(E-F)/G
(1) brackets Е-Е
(2) exponentiation OTs
(3) multiplication/
division L > R A'B Ct3/D (E-FyG
(4) addition/
subtraction L > R (A*B) - (C ^3/D) + (E - FG
Evaluation of —70 +2х ^ x3-3x7
In ZX81 BASIC notation: 40 +2 "4702 "3.8."
Priority 10 4#**2
16
Priority 9 - 70
Negation
Priority 8 2°. te *23 377
LR 96 1
Priority 6 - 70 + 96 — Д1
Result 5
In Spectrum BASIC -70 +2*442*3-3%*7
Priority 10 412
16
110
Priority 9 - 70
Negation
Priority 8 2> 15 "TET
L — R 96 21
Priority 6 - 70 + 96 - 21
Result 9
Exercises
1 Write the order in which the following BASIC expression 1s
evaluated:
— А + ((B**3/C) - (A**2/D))*(E + Е)/С (ZX81)
— А + ((B 13/C)- (A ^ 2/D))*(E+ F/G (Spectrum)
2 Write down the BASIC expressions for:
(i) (и? + 2аѕ)^
(ii) ut + Тағ
жа b + ac)"
(111) 2a
(iv) (xy
Work out the order in which each of the expressions is
evaluated. Test your results on the computer.
J3: Number
À positive or negative decimal number whose magnitude is
between an approximate minimum of:
t3x10 ?
and an approximate maximum of:
+2 x 10”
Zero is included in this range.
The smallest number the computer can handle is
2.9387359 x 10 `”
The largest is:
1.7014118 x 10°
The computer stores and calculates numbers internally to an
accuracy of nine or ten digits, but prints out the results of
calculations to eight significant figures only, rounding where
necessary.
J4: The E Notation
The E or EXPONENT or scientific notation is the notation
computers use for input and output of numbers having a large
111
number of decimal digits. E should be taken to read: ‘times
ten to the power of’. For example:
1.73 E5
is
1.73 times 10 to the power of 5
1.73%10%%5 (1.73*10 ^ 5 in Spectrum notation)
= 173000.
Similarly:
3.8E-7
is
3.8 times 10 to the power of — 7
= 3.8*10** 7 (3.8*10 41 — 7 in Spectrum notation)
= .00000038.
The computer will accept any number keyed-in in this form
and will print out numbers in this notation when their values
are outside a certain range.
For large positive and negative numbers the E notation is
automatically used by the computer for numbers
> = 10?
Numbers up to this figure are first rounded to 8 significant figures and
trailing zeros are added until 107 is reached.
Key in and run this program:
10 LET A = 9.9999993E12
20 PRINT A
30 ІЕТА =А + 1Е5
40 СОТО 20
Change line 20 to read:
| 20 LPRINT TAB 10;A
to get a listing of the result on the printer.
For small positive and negative numbers the E notation is
automatically used for numbers:
<= 10^?
To see this in action, key in and run the program below:
10 LET A-1.000001E — 5
20 PRINT A
30 LETA-A -(1E- 12)
40 GOTO 20
Change line 20 to:
20 LPRINT TAB 10;A
if you want a printer listing of the changeover.
Exercises
1 Key in and run the following simple program, which illustrates
how numbers are printed, the E notation and the largest number
which may be obtained.
112
10 LETA=1
20 LET A=A*10
30 PRINT A
40 GOTO 20
With the ZX81 press and when
the screen becomes full, and the message 5/30 appears on the
bottom of the screen to indicate no more room on the screen.
The Spectrum will display the ‘scroll?’ prompt.
Notice the change to the E notation. Note that the program
finally stops itself on the ZX81 with the error message ‘6/20’,
which indicates an arithmetic overflow (error code 6) as a result
of line 20, i.e. the number is too large for the computer to
handle. The Spectrum's response is more precise; the error code
in this instance will read: ‘6 Number too big, 20:1’.
Change line 10 of the program to each of the following and run
the program each time.
a) 10 LET A=1.00000000
b) 10 LET A=1.1111111
c) 10 LET A=1.7
d) 10 LET A=1.7014118
e) 10 LET A =1.71
What conclusion do you draw?
To show that negative numbers behave in the same way, change
line 1@ to the following and run the program.
a) 10 LET A= -1
b 10 LET A= -1.7
c) 10 LET A= -1.7014118
d) 10 LET A= -1.71
To show how small numbers are handled by your computer a
similar program divides a number (A) by increasing powers of
10.
Key in the program and run it.
10 LET A=1
20 LET A=A/10
30 PRINT A
40 GOTO 20
Note the change of notation.
Notice that after 1E – 38 the computer prints zeros
indefinitely, i.e. it has reached the smallest number it can
register.
Change line 10 to
а) 10 LETA=3
Ы) 10 ІЕТА = 2.9
апа ге-гип the program each time.
Notice that 2.9387359 E — 39 is the smallest number before
zero.
Write this number out in full.
Can you think of any applications for very large and very
small numbers?
113
6 Change the values of À in the program to negative values and
confirm that small negative numbers behave in the same way.
PROGRAMS TO SAVE IN YOUR TAPE LIBRARY
The following two programs should be keyed in, run, listed and saved
for your tape library. They both do what the previous programs did but
in addition give a printed copy of the results.
10 REM "LARGE NUMBERS"
20 REM** PROGRAM MULTIPLIES +
AND - NUMBERS INPUT FROM
THE KEYBOARD BY POWERS O
F 10 **
30 REM **KEY IN VALUES FOR A O
P +-1,,4-1.1111111,4-1..7,. +
-1.7014118,%- 1.71.**
40 INPUT A
50 LET N=0
60 PRINT А%(10%%у)
70 LPRINT TAB 10;A*(10**N)
80 LET N=N+1
90 GOTO 60
For the Spectrum, replace ** by in lines 60 and 70.
10 REM "SMALL NUMBERS"
28 REM**PROGRAM SHOWS PRINTING
OF SMALL NUMBERS**
30 REM**INPUT VALUES OF A AS +
-1, +-2.9,+-3.**
40 INPUT A
50 LET N=0
60 PRINT A*(10**N)
70 LPRINT TAB 10;A*(lQ**N)
80 LET М-М-1
99 GOTO 60
J5: Rounding
ROUNDING UP
The computer will print out computed values to an accuracy
of 8 significant figures, ignoring leading zeros.
Digits after the 8th significant one will be rounded up. For
example, if we key in (as a direct command, followed by
NEWLINE/ENTER):
11%
PRINT 0.111111111 + 0.888888888
the answer on the screen is 1.Try
PRINT 0.0000111111
showing 10 digits can be held exactly.
Adding a one on the end forces the use of the E notation.
ROUNDING DOWN
The INT function returns the nearest integer of the
expression X, which is < = X, i.e. it rounds down.
e.g. INT 3.9= 3
INT -2.8- -3
INT (4 -8.7 +0.8)= - 4
Try printing these functions. Notice that for negative
numbers - 6 is less than - 5, and so on. To round to the
nearest integer add 0.5 to the number first:
e.g. INT (3.9+0.5) = 4
INT (2.4 + 0.5) 2
ІМТ(-1.7-0.5)- -2
ІМТ(-2.3-0.5)- -2
Notice this assumes that 0.5 rounds (о 1.
INT (1.5-0.5) = 2
INT (-1.5+0.5)= -1
Notice we don’t have to enter the zero before the decimal point on the
computer (though it doesn’t matter if we do), it’s in that form here for
clarity.
J6: How Numbers are Handled
All computers perform their arithmetic and processing using
the BINARY NUMBER SYSTEM
In the binary system only two digits are used, 1 and 0. A group of 8
binary digits (bits) is called a BYTE, and we communicate with the
computer in Decimal Notation. This is rather more convenient than
using Binary. Conversion from Decimal to Binary and vice versa is
thus necessary and occurs inside the computer.
One BYTE is equivalent to a single character of the computer’s
character set. A byte represents a number between 0 апа 255
(decimal). ‘This is why the character codes are in this range (see Section
P). A group of 8 zeros and ones can have 2° ( = 256) different states.
A digit or number is represented by one or several bytes according to
its context in the computer.
115
A character input to the computer or output to the screen or printer
is held in one byte. Program line numbers, which are whole numbers 1
to 9999, are held in two bytes.
Numbers are held in a form which occupies five bytes. The point to
be noted here is that conversion from decimal to binary and back is
involved in the operation of the computer, and this conversion is not
always exact. This must be allowed for in certain circumstances,
especially where the computer is asked to check whether two numbers
are equal. A difference in the binary form of the number, however small,
will cause the computer to decide they are not equal. In testing two
numbers for equality, therefore, if non-integer values have been
utilised, and the value of one number arrived at by calculation, the
equivalence check should be replaced by assessing the difference. A
statement such as:
IF ABS(A - В) < 1E-4 THEN...
which checks that the difference between the numbers is less than
.0001, сап be used instead of IF = B THEN ...., if either A or B has
been calculated.
The forms in which numbers are held in the computer are
considered in detail in Section U — the Computer Memory.
J7: Function
We define a FUNCTION as
Y = F(X)
‘Y equals some function of X, F(X)’
A function is the mathematical relationship between two
variables X and Y such that for each value of X there is a
unique value of Y.
Y takes the function value and is the DEPENDENT VARIABLE.
X is the ARGUMENT - the INDEPENDENT VARIABLE.
F is the function NAME, e.g. square root, sine, natural logarithm.
In a program statement we write, for example:
100 LET Y SOR(X)
The argument X can be a single variable, a number or an expression.
If X is a single variable or a number it does not need brackets. If it is an
expression it requires brackets so that the expression is evaluated
before the function is applied to it (so that SOR 9 + 7 gives 10, whilst
SOR (9 + 7) gives 4). For example:
100 LET Y = SOR 9
100 LET Y = SOR(B**2—4*A*C) (B42 on the Spectrum)
We see that a function is a mathematical operation which gives a
number. It is treated in BASIC as a numeric expression, with priority
I.
116
The standard mathematical and trigonometric functions are
important timesavers for programmers. They are the same as the
function keys on scientific calculators. Other functions (utility
functions) control or monitor the handling of data by BASIC rather
than perform mathematics.
If the functions were not available in BASIC we would need to write
separate programs to undertake their tasks every time we had need of
them!
J8: List of Functions used in Sinclair BASIC
In this list of functions X is the argument. X is a variable, a number or
an expression. If an expression, X must be in brackets. Each of the
individual functions will be discussed in more detail later in this
section.
1. Standard Mathematical Functions:
ABS (X) - gives the absolute value of X
EXP (X) - gives e", value of e raised to the power X
INT (X) -gives the largest integer < = X, i.e. rounds down
LN (X) -gives natural logarithm (value of log. X)
SOR (X) -value of V X or X* (X positive)
PI -3.14159265 i.e. value of n, PI, which is how it
prints on screen
SGN (X) -gives sign of X, i.e. whether X is + ve, – ve or
Zero.
2. Trigonometric Functions
SIN (Х) - value of sine X (X in radians)
COS (X) -value of cosine X (X in radians)
TAN (X) -value of tangent X (X in radians)
ACS (X) -angle in radians whose cosine is X
-arccosine Х( - 1 «- X < = 1)
ASN (X) -angle in radians whose sine 18 X
-arcsine X ( -1 <= X < = 1)
АТМ (X) -angle in radians whose tangent is X
- arctangent X
3. Special Mathematical Functions
RND A random number generating function; gives the
next pseudo random number N from a fixed series
of random numbers (0 < = N < 1).
RAND ( RAND 0) starts the sequence of random
numbers in an unknown position.
RAND N (ü0 < = N < = 65535) makes RND always return to
the same value, if N is the same.
117
4. Character and String Functions
CHR$(X) 0<-Х <=255 returns the single character
whose code is X.
CODE A$ When applied to the string A$, it returns the
code of the first character in the string or 0 if the
string is empty (null string).
LEN A$ Returns the number of characters in the string.
VAL A$ Turns a string in number representation into
the number for calculation (e.g. A$ = “12.4”,
VAL А$ = 12.4).
STR$ М Turns the number N into the string “N”.
5. Printing Functions used in the form PRINT F(X)
TAB (X) Places the print position in column X. If X>32
then column number is the remainder when X is
divided by 32. If it involves back spacing, goes
on to next line. Rounds X to nearest integer.
AT (X), (Y) Starts printing at line X, column Y
бжделлбе21. = Y <= 31
Rounds X and Y to nearest integer.
6. Special Functions
INKEY$ No argument. Reads keyboard and senses what
key is being pressed at that time. Returns key
being pressed as a string, e.g. “А” or ‘‘8’’. If no
key is pressed the null string is returned.
PEEK X 0 < = X < = 65535 Returns the value of the byte
at address X in RAM or ROM memory.
USR N Returns the contents of a pair of CPU registers
after running a machine code program from
address N.
N.B. For the Spectrum’s additional functions, see Section W. The
above functions, common to both the ZX81 and the Spectrum, are the
ones used in the main body of the text.
J9: The Function Characters
Each of the functions in Sinclair BASIC is represented on the
keyboard as a single character word.
You don’t have to type the function name letter by letter (if
you try to it won’t work), just press the particular function
key.
Each function character has a special character code and is
part of the computer’s character set. Each of the Function
118
characters on the ZX81 is situated at the same position on
each key, i.e. bottom outside.
To obtain the function the ZX81 must be im FUNCTION
MODE, with the F-cursor on the screen.
On the Spectrum, all functions are obtained in the
Extended mode with the E-cursor on the screen (for further
details see Section W1). All FUNCTIONS treated here are in
green above the key on the Spectrum, with the exception of
ASN, ACS, ATN which are in red below the associated SIN,
COS and TAN functions, although they are still obtained in
the E-mode.
The FUNCTION/EXTENDED MODE only lasts for one
function. To obtain successive functions this mode must be
repeatedly entered.
J10: The Function Character Set
Character Code Code
(7Х81) (Spectrum)
SIN 199 178
COS 200 179
TAN 201 180
INT 207 186
RAND 64 249
STR$ 213 193
CHR$ 214 194
CODE 196 175
PEEK 211 190
TAB 194 173
ASN 202 181
ACS 203 182
ATN 204 183
SGN 209 188
ABS 210 189
SQR 208 187
VAL 197 176
LEN 198 177
USR 212 192
LN 205 184
EXP 206 185
AT 193 172
INKEY$ 65 166
NOT 215 195
п (PI) 66 167
These are the function characters as represented on the ZX81
keyboard. NOT is dealt with in Section R and INKEYS in Section K.
Note that ARCSIN, ARCCOS and ARCTAN are used on the ZX81
keyboard but print as ASN, ACS, АТМ, and п prints as РІ.
J11: The Standard Mathematical Functions
ABS (X)
Returns the absolute value or modulus of the value X.
X may be a number, variable or expression.
ABS(X) gives us the positive value of X. For example:
10 PRINT ABS( - 3.7) gives 3.7
10 PRINT ABS (4) gives 4
Exercises
Key in and run this program:
10 INPUT A
20 INPUT B
30 PRINT TAB 3;A; TAB 10;B
40 PRINT TAB 3; ABS (A - B)
30 GOTO 10
Input positive and negative values for A and B.
Now change line 40 to:
40 PRINT TAB 3; ABS (A*B)
and input some more values. Try replacing the * with **
( ^ Spectrum), or using ABS (SOR А).
N.B. ABS (- 3**3) , or expressions in similar form will not work
as the ** ( ^ Spectrum) operator only works for positive first operands.
EXP (X)
Where X is a number or an expression EXP (X) gives the
value of the constant e raised to the power of the value of X
e — 2.7183
e.g. 10 PRINT EXP (3.4)
i.e. 10 PRINT (2.7183* *3.4) (2.7183 1 3.4 on Spectrum)
The function EXP is the inverse to LN.
Exercises
1 Using log tables write a program to check the values of e* given
in the log tables.
120
2 Write a program which will calculate O from the expression:
Q = Qo.e-"* (In BASIC Q = QO* ЕХР(-Т/К“С))
If you know anything about electricity, you might recognise this
expression.
3 Key in this program. It calculates a value for e from the formula:
e=(1+1/N)**N (^N оп Spectrum)
where N is very large. Spectrum users should replace ** by # in
lines 30 апа 40.
10 REM “VALUE OF E"
20 ІЕТІ- 1
30 LET N=10**I [^Spectrum]
40 LET E=(1+1/N)**N
50 PRINT TAB 1;N;TAB 12;E
60 LET I=I1+1
70 IF l=5 THEN STOP
80 GOTO 30
LN (X)
Gives the value of the natural logarithm.
LN (X) = Log, (x)
Note that log, (X) (common logarithm)
= ( LN(X) )/( LN 10 )
The LN function is the inverse of EXP
So: If EXP (X) = Y
Then (X) = LN(Y).
LN (Y) is the natural logarithm of Y. The antilog is EXP(LN(Y)). The
normal log operations can be used if appropriate, as with common logs.
For example EXP(LN (X) + LN (Y)) gives the product of X and Y.
Exercises
1 10 LEFY=1
20 PRINT TAB 3;Y; TAB 10; ЕХР (LN Y)
30 LET Y=Y+1
40 GOTO 20
Key in and run this program which proves the relationship
between the EXP and LN functions.
2 Change 30 to: 30 LET Y = Y*1@ and run again.
SQR (X)
The function SQR returns the square root of (X), V (X) or
Х95, For example:
121
PRINT SQR 9 gives 3
PRINT SQR 23 gives 4.7958315
PRINT SQR (19 + 17) gives 6
PRINT SOR (ABS - 25) gives 5
SGN (X)
SGN (X) returns + 1 if (X) is positive, 0 if (X) is zero, — 1 if
(X) is negative.
SGN is short for Sign or Signum (Signum doesn’t sound like
Sine). For example:
SGN 23 gives 1
SGN - 5 gives - 1
SGN (3 – 3) gives Q
SGN 1 gives 1
SGN (25 - (2*23)) gives — 1
п PI
T (which prints on the screen as PI) is a function which has no
argument. It returns the value of r as 3.1415927.
3.1415927 is what prints on screen for PI. How would you test whether
the computer held any more digits of PI in memory? What happens
when you take away 3 from PI?
J12: Trigonometric Functions
SIN COS TAN
The functions SIN (X), COS(X)and TAN(X) give the value of
the sine, cosine, and tangent of the number or expression X,
which is an angular measure. X must be in RADIANS.
We normally express angles in DEGREES.
PI
= өй. 9... dE. Š
1 DEGREE 180 RADIANS (1 180 radians)
To convert degrees to radians multiply by PI/180. For
example, if Y is our measure of angle in degrees then:
SIN (Y*PI/180)
gives the correct value of Sine Y.
Exercises
1 Generate a table of values for SIN (X), COS (X) and TAN (X)
122
for every 20 degrees in the range 0 — 360 degrees.
2 Write a program to verify the trigonometric formula:
SIN(XX)+COSXX) =1
1+ TAN XX) =SEC*X)
3 Write a program to calculate the area of a triangle from a
knowledge of the length of 3 sides and an angle.
ACS ASN ATN
The functions:
ACS (X), ASN (X), ATN (X)
give the arc cosine, the arc sine and the arc tangent,
respectively, of (X).
The returned value is the angle in RADIANS for which the
cosine, sine or tangent would be given by the value of (X).
To get the angle in degrees multiply by 180/PI e.g.
Y = 180/PI*ACS(X) gives arcsin (X) in degrees.
Notice these functions print as above, but appear on the ZX81
keyboard as ARCSIN, ARCCOS, ARCTAN.
J13: Special Functions
Random number generators are useful for games and simulation in
statistics. The numbers generated are part of a very long sequence of
numbers (there are 65536 of them) and are in fact only ‘pseudo-
random’, but good enough for our needs.
RND
RND gives a random number greater or equal to zero but less
than one.
10 LET A = RND
assigns a number in the range 0 < = N <1 to the variable A.
Notice RND has no argument.
If we key in PRINT RND we get a number like .0011251904 or
0.43715682 which is eight or ten digits long and is not much use to
anybody in this form.
We need to be able to generate random numbers within a useful
range, according to our purposes:
1. To obtain a Random Number 0 - 9
To obtain a random number from 0-9 we must multiply our
123
function by 10 and take the integer value.
i.e. PRINT INT (RND*10)
RND*10 gives random numbers between 0.00000000 and
9.9999999, IN'T( ) will round these values down to integers
0 to 9.
2. Numbers 1-10
Although @ to 9 gives us ten values the range 1 to 10 would be
more useful. This is obtained by adding one to the RND function:
PRINT INT (RND*10 + 1)
Suppose we wanted random numbers generated for simulating a
dice roll, we would use:
PRINT INT (RND*6 + 1)
3. Random Numbers for a Card Game
There are 4 suits, with 13 cards per suit = 52 cards. So if we used:
PRINT INT (RND*52 + 1)
we could select cards at random.
Think about how you could identify the suits and not deal the
same card twice.
4. ‘Tossing a Coin
There are two outcomes, head or tails, so:
10 LET A= INT(RND"?2 + 1)
20 IF A=1 THEN GOTO 50
aD PRINT “TAILS”
40 GOTO 10
50 PRINT “HEADS”
60 GOTO 10
This program will toss coins until we use BREAK.
RAND N
RAND is a keyword and is used for controlling the
randomness of RND.
The computer has a fixed sequence of 65536 jumbled up
numbers. RAND N will start RND reading numbers from the
Nth number in the sequence.
Key in and run this program to prove the above:
10 RAND 7
20 LET Ce=1
30 PRINT RND
40 LET C-C-«1
124
50 IF C<6 THEN GOTO 30
60 GOTO 10
Not amazingly random after all!
Exercises
1 Write a program which throws three dice and prints the values
thrown across the screen.
2 Write a program to check that the number generated by RND
using RAND N is given by RND = (75*(N + 1) - 1/65536).
3 Modify the coin tossing program to count the number of times
heads or tails have come up (you need one variable for each).
When you've stopped the program by pressing BREAK, you
can then access the values by keying in PRINT HEADS, or
whatever your variable name is, as a direct command.
4 Write a program to print four groups of three random numbers
in the range 1 to 52.
125
SECTION K: STRINGS
K1: Strings
A string is a set of characters enclosed by quotation marks,
e.g. “THIS IS A STRING” or the null string (no characters
Typical Strings: “BALL OF STRING"
“JANUARY 1ST 1982”
“URGHH!”
“FAB ** — +/!3”
E " (String of spaces)
1234”
ore (Null string)
Computers handle two kinds of DATA:
NUMERIC - numbers
ALPHANUMERIC - names or TEXT.
The way a computer deals with text is called STRING HANDLING.
Strings deal with ALPHANUMERIC information.
The sequence of alphanumeric characters is handled in a string as a
single unit of data.
Characters are defined as LITERALS when placed inside quotes
“> They are taken literally to represent themselves. Strings are
therefore literals.
Characters are IDENTIFIERS where they are not enclosed in
quotes. Thus, for example, A represents or identifies a numeric
variable and A$ identifies a string variable.
Strings can either be of FIXED LENGTH-e.g. always 10
characters long - or VARIABLE LENGTH. The fixed length is
determined by the string dimension instruction:
DIM A$ (N)
where N is the length in characters.
Characters which cannot be used in strings
A string cannot contain a character that is a line terminator:
NEWLINE (ENTER) or TAB. Nor can it contain any of the
following:
EDIT
GRAPHICS
RUBOUT (DELETE)
FUNCTION
BREAK
ee
(single quotes)
126
All other characters in your computer’s character set can be used.
Run the program which checks this:
10 INPUT A$
20 PRINT A$
30 GOTO 10
Now try and input some of the above characters.
Examples of the sort of text we may want the computer to handle
are:
— a telephone directory
- names and addresses
- a timetable
- expenses details
Computers store all this textual information as strings.
String manipulation by the computer would, for our first example,
need to deal with:
creating the telephone directory
sorting the names and numbers into the correct order
searching the directory for somebody's number
revising the directory, i.e. updating or adding an entry
printing out the directory in whole or part.
K2: Quotes and Quote Image
QUOTES
All strings are enclosed in quotes ‘‘’’ when:
(1) They are to be INPUT from the keyboard, as in a program
line such as: 10 INPUT A$ . When the line is run the
cursor оп the screen appears already enclosed in quotes |1 |”.
You key in just the characters wanted in the string.
(2) When used in programs with the PRINT instruction, e.g.
20 PRINT ‘‘STRING’’.
(3) When assigned in a program to a string variable, e.g. 30
LET А$ = * STRING".
THE QUOTE IMAGE KEY
ON THE ZX81
The QUOTE IMAGE is a special single character on the shift
keyboard of the ZX81.
6699
It is used to write ordinary quotes in the middle of a string.
eg.10 PRINT "SAY “BELLO” TOO]
127
When the line is run the double quotes will be printed on the screen as
single quotes:
SAY “HELLO” TOO
A special character is needed as two single quotes won’t work.
Key in and try to run each of the following lines:
10 PRINT '' SAY “НЕТО”? ТОО”
10. PRINT “БАУ”; "HELLO"; "TOO"
10 PRINT “ SAY "HELLO" TOO"
The Spectrum has no QUOTE IMAGE character. Instead, you must
put two quotes for every one you want printed. For example, to obtain
double quotation marks you type in PRINT“ °>, Single quotes
are obtained with PRINT**** ’’’’. Program listings look the same for
both machines.
K3: String Input
On running 10 INPUT A$ the letter cursor appears at the
bottom of the screen with quotes round it, prompting you to
key in characters for the string
= [L] =
On the Spectrum this can also be the C-cursor - ‘‘ me
STOPPING STRING INPUT
When keying in the characters for the string to be input notice
that BREAK and STOP have no effect.
To escape (1) Use the < key to get outside the quotes.
(2) Press STOP, NEWLINE (ENTER)
or
press
|
There is a special form of string input, using the INKEYS instruction:
INKEYS$
When INKEYS is encountered by the computer it reads the
keyboard to determine if a key is being pressed. It does not
wait for input like the INPUT instruction. If a key is being
pressed it returns the string containing the mode
character of the key being pressed. If no key is being pressed
it returns the empty string ‘‘’’.
128
The Spectrum returns the mode character with INKEYS$ if in the
CAPS mode.
We can spend as long as we want before we input a string with the
INPUT command, since the cursor will remain on screen. If we want
to take advantage of the fact that, unlike INPUT, INKEYS does not
require NEWLINE(ENTER) to be pressed, we must arrange a delay.
Try this program:
10 PRINT “PRESS A KEY WHEN READY”
20 IF INKEY$-''"" THEN GOTO 20 (no spaces)
30 LET AS-INKEYS$
40 PRINT “YOU PRESSED ”;А$
Line 20 sends the program back to the beginning of line 20 as long as
no key has been pressed. Line 30 makes A$ the single character string
returned by INKEY$ when a key is pressed.
Due to a design error the Spectrum has far less predictable keyboard
scanning using INKEYS than the ZX81. If you type in the program as
above on the Spectrum it will work about half of the time. The rest of
the time it will skip over line 30. This program will work every time
though:
10 PRINT “ PRESS A KEY WHEN READY"
20 PAUSE 0
30 PRINT “YOU PRESSED ”’;INKEY$
Experiment with the two versions to see this problem in action. The
action of PAUSE 0 is to stop until a key is pressed. The first key
pressed will be the INKEY$. PAUSE will be dealt with later, but
remember this quirk of the Spectrum, and this method of dealing with
it. The rule is to use PAUSE 0 immediately before INKEYS is used in
a program line, to wait for input.
Now enter and run this program:
10 PRINT “PRESS 6”
20 IF INKEY$ =“
THEN GOTO 20 (on the Spectrum 20 PAUSE 0)
30 IF INKEY$ = “6” THEN GOTO 60
40 PRINT “FOLLOW INSTRUCTIONS"
50 GOTO 20
60 PRINT “ENDING PROGRAM NOW"
70 STOP
Line 20 does the same as before, but line 30 now checks that the right
key has been pressed. Notice the 6 must be enclosed in quotes, because
INKEYS returns a string. If 6 was pressed, the program goes to line 60.
If any other key was pressed, it goes to 40, prints the message, and then
is sent back (line 50) to line 20, which waits for another key to be
pressed.
Games programs, which require interaction, often use INKEY$ in a
loop, so that every time the program loops, it checks which key, if any,
Is being pressed.
129
K4: Length of a String
LEN
The length of a specified string A$ is obtained by using the
function: LEN A$. The length is given as the number of
characters and is the current length of the string.
Spaces are included in the length of a string.
EXAMPLES
1 10 LET A$=‘‘SINCLAIR”’
20 PRINT LEN A$
Check that the result is 8.
2 10 LET AS= “А B’’ (9 spaces between A and B)
20 PRINT A$
30 PRINT LEN A$
Key in and run.
3 10 LET A$- “PRINT”
20 PRINT A$
30 PRINT LEN A$
Key in the program first with PRINT formed from separate keys, and
then change line 10 so that PRINT is formed by pressing the
key.
Why are the answers different?
4 10 INPUT A$
20 PRINT A$, LEN A$
30 GOTO 10
K5: Null Strings
A string with no characters is called a null string. For
example:
LET A$ — 6699
The length of the string is 0.
A string which contains spaces is not a null string. A space is a character
obtained by pressing [SPACE] . The null string is returned by
INKEYS if no key is being pressed.
Exercises
1 Key in and run the following program:
10 ТЕГА"
130
20 PRINT A$
30 PRINT LEN A$
2 Key in and run this program:
іё LET A$e!' ”
20 PRINT A$
30 PRINT LEN A$
К6: String and String Array Variables
AS
is a string variable used to store strings. It consists of a single
letter (À to Z), followed by the dollar sign.
Twenty-six variables of this type are thus possible.
The Spectrum accepts upper and lower case letters, but treats, e.g. k$
as the same string as K$.
AS(N)
is a string array variable or string list variable where N refers to
the number of strings in the list. String lists must be
dimensioned as an array before the string array variable can
be used, by the DIM (DIMension) instruction.
Using the array notation, an unlimited number of string
variables are possible.
Again, the Spectrum accepts upper and lower case letters, but does not
differentiate, e.g. b$(N) and B$(N) are the same.
Caution: A$(N) can have two meanings in a program.
(1) It can refer to the N’th character in a string A$.
(2) It can refer to the N'th string in a list or array of strings. In this
case the string array must previously have been dimensioned with a DIM A$(N)
instruction.
K7: String and String Array Dimension
STRING DIMENSION
DIM AS(N)
sets a fixed length of N characters for the string. For example:
10 DIM А$(6)
sets a length of 6 characters for the string А8.
131
If strings of length <N (less than N characters) are assigned or input,
then space characters are added to make up the complete string of
length N. Spaces do not show up on the screen when they are printed!
(To check they are in the string we can ask for their character set code
to be printed using the CODE instruction. We'll get to this later.)
If more characters than the number allowed in the DIM AS$(N)
statement are assigned from INPUT or LET statements they are
ignored. If strings are not dimensioned their length is effectively
unlimited.
The DIM statement fixes the length of a string until changed by
another DIM statement. LEN is thus not useful when strings are
dimensioned.
STRING ARRAY DIMENSION
The DIM statement for string arrays has the form:
DIM A$ (N,L)
where N = number of strings and L = the fixed length of each
string. A may be any single letter A to Z, but must NOT be
the same as a simple string variable. Each string is set to
contain L spaces initially.
For example, DIM A$(3,4) will reserve storage space for 3
strings, A$(1), A$(2), A$(3), each of length 4, іп the string
array A$.
K8: String and String Array Assignment
STRING ASSIGNMENT
Strings are assigned to string variables using the LET or
INPUT instructions. For example:
LET A$ = “А STRING"
or INPUT A$
This establishes a value for the string.
As we shall see later, the value may be a literal value in quotation
marks, or a string or substring value.
STRING ARRAY ASSIGNMENT
5 DIM А$(3,9)
10 LET AS(1)- “SINCLAIR”
20 LET А%(2)- ‘‘COMPUTING’’
30 LET А$(3) = *COURSE"
assigns 3 strings to the string array variable А$(3).
132
We can also use an INPUT instruction:
10 INPUT А%(1)
20 INPUT A$(2)
30 INPUT А$(3)
Exercises
1 Key in and run this program:
10 DIM A$(2,9)
20 LET A$(1)- “PERSONAL”
30 LET A$(2) = 'COMPUTING "
40 PRINT А$(1), A$(2)
2 Now key in and run this. Input different strings of varying
length. The string length is set at 8 in line 10.
10 DIM AS$(3,8)
20 INPUT AS(1)
30 INPUT А$(2)
40 INPUT А$(3)
50 PRINT А%(1)
60 PRINT А%(2)
70 PRINT А$(3)
3 Key in and run this program:
10 DIM AS(6)
20 INPUT A$
30 PRINT AS$
40 PRINT LEN A$
50 PRINT АФ “ЕМГ”
60 GOTO 20
line 10 sets a length of 6 characters for A$
line 20 asks you to input a string
line 30 prints the string
line 40 prints the size of the string in terms of characters
line 50 prints END starting directly after the 6th character in
the string
line 60 loops us back to input another string
a) INPUT less than 6 characters.
See that the remaining characters are spaces. Notice that
LEN A$ always gives 6 even though different numbers of
characters are input for А8.
b) INPUT 8 characters.
Notice the extra characters are ignored.
K9: Substrings and String Slices
A SUBSTRING or a STRING SLICE is any set of consecutive
characters taken in sequence from the parent string. For
133
example, for the string – “ABCDEFG'”:
a substring 15 “СПЕЕ”
or “АВС”
or шм Ы
А substring сап Бе а single character.
SPECIFYING SUBSTRINGS
AS(P TO Q)
«ANYSTRING" (P TO Q)
where P is the first character and Q the last character of the
substring wanted іп the strings A$ or ‘‘ANYSTRING’’.
SUBSTRING ASSIGNMENT
Any substring is itself a string. We can assign a string to a substring:
10 DIM А$(12)
20 LET A$ (1 TO 4) = “JOHN”
30 LET A$ (6 TO 10)- *SMITH"
40 PRINT A$
This program assigns strings to substring variables.
EXAMPLES
1
2
3
10 PRINT “SINGLAIR” (2 TO 5) prints INCL
10 РКІМТ “SINCLAIR” ( ТО 3) prints SIN, since 1 15
assumed if it 1s omitted at the start.
10 PRINT “SINCLAIR” (3 TO ) prints NCLAIR (omitting
the character after TO means the last character in the string 15
assumed).
10 PRINT ‘‘SINCLAIR” (3 TO 3) prints М.
This is more conveniently written as
10 PRINT “SINCLAIR”” (3)
Or
10 LET A$- ‘‘SINCLAIR”’
20 PRINT А$(3)
which prints the 3rd character in A$, exactly as with a literal
string. |
10 PRINT “SINCLAIR” (1 ТО 0) prints 4”
1.е. gives the null string (по characters).
Here is a program that uses names and numbers in single
strings:
134
10 LET А%-"МАМЕ AGE"
20 LET BS="TOM 16"
30 LET C$z"BILL 14%
40 LET D$=" JANE 17"
20 PFINT АТ 1567;AS$C1 TO 4); АТ
1:14:8%(6 TO 8)
£20 PRINT АТ 4.,&:E$C1 TO 4); AT
4; 14:Е%с(6 TO 7)
70 PRINT АТ 7s6*C$(1 TO 4); AT
7%:14:С%(6 TO 7)
SO FRINT АТ 1016; D$(1 TO 4);
АТ 10:14:1%(6 TO 7)
Notice how we spread the print out using substrings.
K16: String Concatenation
A$ + B$
Concatenation means chaining strings together. It is derived
from the word catenary meaning a chain. What the computer
does is to ‘add’ them together to form a new string.
“СОМ” + “PU” + “TER” = “COMPUTER”
10 LET A$ = “СОМ”
90 LET B$ = “PU”
30 LET C$ = “TER”
40 LET T$ = A$ + B$ + C$
50 PRINT T$
Note that the + operator is used for string concatenation.
We cannot subtract, multiply, divide strings or raise them to powers,
because they are not numbers. Although the ‘adding’ of concatenation
uses the same symbol it is not an arithmetic operation.
Key in and run the example program given above.
Add some DIM statements to the program:
2 DIM А%(6)
4 DIM В5(6)
6 DIM C$(6)
Run it. You will notice that although the strings are chained they are
far apart. Why is this?
Now try this program:
10 INPUT А5
20 INPUT BS
30 PRINT А5,В5,А5%В65
40 LET AS = А54В5
50 PRINT А5
60 LET А$=А$+А$
70 PRINT А5
Notice іп line 40 уге have incremented the string Бу adding B$ оп to
A$. This gives us a new A$ made up of the old A$ plus B$. The
statement in line 60 is equivalent, in string terms, to having a line
which for numeric variables says LET A= A+A.
K11: Comparing Strings
The conditional operators:
= <> <= < >= >
may be used between strings and string variables using the
IF... THEN instructions. For example:
IF A$ = “YES” THEN GOTO ....
IF N$ = B$ THEN PRINT ....
IF A$< = B$ THEN GOTO ....
When the computer compares strings of characters it does so by
comparing the codes of each of the characters in sequence. A string is
found to be less than another if it comes first in alphabetic order. If the
strings contain numbers we should remember that numeric codes are
less than alphabetic (letter) codes. This affects comparisons. (See
Section P for the character codes.)
Strings are compared in order of characters from left to right. For
example:
“AS, ЗЫ”
"AD S A
“А”< “АА”
a d.e d
“АЗ S “А4”
“б” "LE
= A “4Д”
Key їп and run the next program. Input the strings above plus others
you want to try and it will print out their relative alphabetic orders.
10 INPUT A$
20 INPUT BS
30 IF А5<В5 THEN GOTO 70
40 IF А5-В5 THEN GOTO 99
50 PRINT А5;">";В5
60 5ТОР
70 PRINT A$;"«"; BS
80 STOP
90 PRINT A$;"-";B$
100 5ТОР
136
This gives us a method for putting names into alphabetic order, like in
a telephone directory. We also have a method of searching it, since we
can check whether any name in the list is equal to the desired name.
We have already used string equality, but here’s another example of
string comparison:
10 PRINT "DO YOU UNDERSTAND STRINGS?"
20 PRINT “ANSWER YES OR NO"
30 INPUT А5
40 IF AS = "YES" ТНЕМ GO ТО 70
50 PRINT “THEN READ THE SECTION AGAIN!"
60 STOP
70 PRINT "YOU ARE A GENIUS!"
88 STOP
Key it in and run it. Do you understand?
The above assumes the use of capital (upper case) letters only on the
Spectrum. For lower case letters, these are all after upper case letters in
the ordering of strings. So on the Spectrum:
AA<Aa
Z<a
Z1<z1
SMITH<Smith
So any ordering of strings must take this into account. For this text we
assume the use of capitals throughout.
Exercises
1 The “TELEPHONE” program sets up a telephone directory
with names and telephone numbers. It will search through its
lists to find the telephone number corresponding to a given
name. Run and analyse the program to find out how it works.
10 REM "TELEPHONE"
20 REM **PROGRAM SETS UP A TEL
EPHONE DIRECTORY AND USES IT**
30 PRINT "HOW MANY NAMES DO YO
U WISH TO ENTER INTO THE DIRECTO
Ry?"
40 INPUT N
50 PRINT
60 PRINT “INPUT ";N;" NAME (20
LETTERS) AND NUMBER(8 FIGS) PAIR
5"
70 DIM А$ (М, 20)
80 DIM BS(N,8)
90 DIM DŠ (20)
100 PRINT
137
110 PRINT
120 PRINT "NAME";TAB (22); "МОМВ
ER"
130 PRINT
140 FOR F-1 TO N
150 INPUT А$Ѕ (Е)
160 PRINT AS(F);
170 INPUT BS(F)
180 PRINT TAB (22);BS$(F)
199 NEXT F
200 PRINT
210 PRINT
220 PRINT "TO CLEAR THE SCREEN
TO USE THE DIRECTORY PRESS CONT
AND NEW LINE KEYS"
230 STOP
240 CLS
250 PRINT
260 PRINT "WHAT NAME?"
270 INPUT D$
280 REM **NEXT PART OF THE PROG
RAM SEARCHES FOR THE NAME**
290 PRINT
300 PRINT D$;
310 FOR F=1 TO N
320 IF AS(F)-DS$ THEN GOTO 370
330 NEXT F
340 PRINT
350 PRINT "NAME NOT FOUND"
360 GOTO 260
370 PRINT TAB (22);BS(F)
380 PRINT
399 PRINT
400 PRINT "ANOTHER МАМЕ? (Y/N)"
410 INPUT QS$
420 IF Q$-"Y" THEN GOTO 249
430 PRINT
440 PRINT "TO KEEP YOUR DIRECTOR
Y AFTER SAVING, USE ""GOTO 240""
WHEN RUNNING THE LOADED PROGRAM
қ NOT ""RUN"","
450 PRINT
460 PRINT "BYE FOR NOW"
470 STOP
2 Modify “ТЕГЕРНОМЕ” to create your own directory with
your friends’ names and addresses or birthdays or telephone
numbers.
a) Redesign the program
b) Document it
c) Key it in
d) SAVE it
e) Debug it
D LLIST it
g) SAVE the working version
h) Put it in your personal tape library
1) Enter details in your notebook
138
K12: Strings and Numbers
In addition to the handling of strings as strings, there are instructions
which enable us to convert strings to numbers, numbers to strings, and
to usefully manipulate various numerical values of strings and their
characters. We have already dealt with LEN. The other available
string functions are dealt with here. The first two instructions cover the
character set which is dealt with in Section P.
CODE A$
When applied to a string A$ CODE returns the character set
code number of the first character in a string. For example:
10 LET X = CODE “MOTHER”
On the ZX81 X becomes 50, the code for M (CODE “М”).
When applied to a single character substring, it returns the
code of the substring:
e.g. 10 LET A$ = “CODE”
20 PRINT CODE А$(3)
prints 41, the CODE for D (CODE ‘‘D’’).
The Spectrum uses a different code to the ZX81 (called
ASCII, an international standard). Thus, CODE
“MOTHER” is 77, and CODE А$(3) in the above is 68
(= CODE ‘‘D’’).
CODE A$ (M,N)
When applied to a string array CODE returns the character
code of the N’th character in the M’th string. For example:
10 DIM A$(10,10)
20 LET A$(1)- ‘‘SINCLAIR’’
30 LET А$(2) = “BASIC”
40 PRINT CODE A$(2,3)
will print 38 (CODE‘‘S’’) on the ZX81, whilst on the
Spectrum the *S' in ASCII code is 83 (there is no significance
in one being the reverse of the other!).
CODE А$(2), applied to a string array as above, would return the
CODE of the first character in A$(2), just as when applied to a literal
string or string variable.
139
CHR$
When applied to a number М, CHR$ N gives the single
character string in the computer’s character set whose code is
the number N.
For example, on the ZX81:
CHR$ 49 15 “L”
CHRS 12 is “£”
whilst on the Spectrum CODE ‘‘L”’ is 76 and CODE *'£" is
96, so CHR$ 76 gives “1.” on the Spectrum, and CHR$ 96
gives **£^',
We can treat these characters as elements in a string and make up a
word by concatenation. Try this on the ZX81:
10 LET A$=CHR$ 63 + CHR$ 61 + CHR$ 36 + CHR$ 29
20 PRINT A$
or this on the Spectrum:
10 LET A$=CHR$ 83 + CHR$ 80 + CHR$ 69 + CHR$ 67
+CHR$ 84 + CHR$ 82+ CHR$ 85 + CHR$ 77
20 PRINT A$
VAL A$
Applying VAL to a string containing only numeric characters
and arithmetic or logic operators, returns the result of the
arithmetic inside the string.
For example:
10 PRINT VAL ‘14+2+3”’
prints 6
10 LET A$= 43”
90 LET BS =**4”
30 PRINT VAL (A$ + B$)
prints 7
All recognised arithmetic functions can be used:
10 PRINT VALSSOR 16"
(prints 4)
10 PRINT VAL “ABS -29”
(prints 29)
An interesting use of VAL is where alphabetic and numeric
information in a string can be treated as substrings. Arithmetic can
140
then be performed on the numeric substring. For example, try this
program which gives
the total ages of three people in a group.
LET ñ$="SMITH 23"
LET ES="JONES 24"
LET C$z"WEZT 17"
LET T= VAL A$ca TO 93+ VAL
BELS TO 935 VAL СФЕ TO 99
PRINT AS
РЕІМТ E$
PEINT C$
PRINT з» “TOTAL AGE "FT;
"^ YEARS“
STR$
STR$ (N) returns the value of (N), a numeric expression, as a
string. For example:
STR$ 3.4 gives “3.47
STRS$ (3*31) gives “93”
STR$ (SOR 4) gives ‘‘2”’
STR$ is the complementary or opposite function to VAL
To see STR$ in operation, and the complementary functions of VAL
and STR$, try this program:
10
20
Exercises
LET X23
LET Ү=0. 5
LET А%= ZTR$ (X/Y)
FEINT A$, VAL AS
(ЕТ BS=AG+ 5ТК% X
PRINT E$, VAL ES/2
LET t= VAL С STRE С VAL AS+
VAL ЕФ)?
PRINT С
1 Write a program which inputs a number of strings
calculates the total number of characters in each, and the total
number of characters in all the strings.
2 Write a program which calculates the total price of items in a
shopping list, after receiving and printing out the string inputs of
each item and
its cost.
and
3 Write a program which will print a calendar for any month of
next year. Key in the month names and lengths as a string in the
program.
141
SECTION L: LOOPS
L1: Loops
A loop is a block of instructions that the computer executes
repeatedly until a terminating condition is met.
The usefulness of loops can be seen by considering three forms of a
program to print out the first one hundred positive integers.
10 PRINT 1
20 PRINT 2
30 PRINT 3
9 Ww $ 6 P»
ce te @ S
1000 PRINT 100
This program, which does not use a loop, is 100 statements long. This
next program uses a conditional jump loop which does the same thing and
uses only five statements.
10 LET C=90
20 LET C-C-«1
30 PRINT C
40 IF C< 100 THEN GOTO 20
90 STOP
The third program uses a FOR - NEXT loop which is the commonest
method of looping in BASIC, and the most economical in program
lines.
10 FOR F - 1 TO 100
20 PRINT F
30 NEXT F
40 STOP
All loops have four characteristics:
1 Initialisation (start value of counter)
2 BODY of loop
3 Modification oí counter
4 Exit condition.
Loop structures may be properly formed in two ways:
1 CONDITIONAL GOTO STATEMENT LOOPS
2 БОҚ... NEXT LOOPS
Loops are extremely useful. They allow repeated procedures to be
performed, and the values of the counters, which are modified each
time the program passes through the body of the loop, may also be used
in calculations, if care is taken.
142
L2: Counters
Here are two examples of the use of the conditional GOTO loop:
19 LET C=0
ZO LET Себа
30 FRINT "COUNTING"
40 IF C “= 10 THEN GOTO 20
90 PRINT "FINISH"
10 LET С=0
20 LET CsC*1
20 INFUT A
40 FRINT А
ФО IF Cz10 THEN GOTO 20
60 PRINT “END OF NUMBERS"
The variable C is used as a counter in these programs, adding 1 every
time the program loops. 7f the value of C is less than the value set then
the GOTO statement is executed and the program loops. If it is greater
then control passes to the next program line. This enables us to control
the number of times the program lines within the loop are executed.
Our procedure for using counters in the example programs above is:
1 Initialise the counter
2 Increment the counter (add 1)
3 Do the task
4 Check the counter. If it has not reached the final value then go
back to item 2. If it has then program exits from the loop.
Note that we can perform the incrementation of the counter in a
different place:
1 Initialise
2 Do the task
3 Increment counter
4 Check the counter. If less than specified value, GOTO 2. If
more than specified value, program exits from the loop.
We must be careful to set the conditions properly to achieve our desired
result (the correct number of passes through the loop). Look at the first
two simple programs above again. How many times will each of them
pass through the body of the loop? Which is wrong if we wanted to loop
exactly ten times? If you don’t see the answer, key them in and run
them.
The GOTO statement in the program below enables the program to
loop continuously between lines 50 and 80. This would continue
indefinitely so it is important to get out of the loop at the appropriate
point. This is achieved by line 60 utilising the IF (condition) THEN
GOTO (line-number) statement. Notice that the value of the counter
(N) 1s used inside the loop:
143
„Ө REM "SIMPLEI"
20 PRINT “SEVEN TIMES TABLE"
ЗО PRINT “UP TQ TIMES 20"
40 LET N=0
20 LET N=N+1
&O IF М>20 THEN GOTO 100
70 PRINT N+ 7#N
so GOTO 50
100 REM **#ЕМП++#
Notice that the counting procedure in this program is set up differently
again. Line 50 increments the counter. Line 60 checks the counter
value. In this case, the IF- THEN statement has the effect of
transferring control out of the loop if the counter exceeds 20, with the
GOTO 100 statement.
The procedure in this case is:
1 Initialise
2 Increment
3 Check counter. If greater than specified
value, jump to program end.
4 Body of loop
5 Return to 2.
Key in the program. Run it to check it loops exactly twenty times.
Then EDIT line 60, to insert:
75 IF N> 20 THEN GOTO 100
and delete line 60. Now run it. It is surprisingly easy to miss the
desired number of loops, if you are not careful with the structure of the
loop, and the exit conditions. (Change N220 in line 75 to N> = 20 and
the program will loop the correct number of times).
Different procedures using counters give different program
structures. Look at the flowcharts of different counter procedures.
Remember that the conditional test can put to use the >, <, >=,<=,
= operators, as appropriate.
144
COUNTER FLOWCHARTS
Counter =
Start
Value
Counter =
Counter +
Step
of loop
Exit Loop
145
Yes
Counter
= Ətart
Value
Body of Loop
Counter
= Counter
+ Step
Counter
= Finish
Value
No
Exercise
Consider a simple program to work out the squares of the first 20
integers.
19 PRINT "NUMBER", "SQUARE"
20 LET М-й
30 LET N=N+1
40 IF N»20 THEN GOTO 70
50 PRINT N,N*N
60 GOTO 30
70 REM*END OF PROGRAM*
146
The GOTO statement in line 60 will cause the program to loop
continuously between lines 30 and 60.
This would continue indefinitely but line 40 is inserted so that the
program jumps out of the loop when N>20.
N is used as a counter. Line 20 initialises N and line 30 increments
N by 1 each time the program goes round the loop.
Write a program which calculates and prints the square and the cube
power of even numbers between 10 and 30. The counter will need to be
incremented by 2 each time the loop is executed by a GOTO
statement.
Write a program which loops 10 times (counter 1 to 10) but uses
another counter to print the squares of the ten numbers 5.25, 5.0, 4.75
са. 3.0.
L3: For – Next Loops
This is a more convenient way of having a program loop. The loop is
set up with the FOR... TO ... STEP and NEXT instructions used in
combination. The loop goes from the first value to the last value,
counting by adding the defined STEP value every time it loops until
the exit condition is met.
FOR (variable) = (first value) TO (last value) STEP (step)
FOR C = (N) TO (M) STEP (X)
where C is the counter variable or control variable of the loop
and (N), (M) and (X) are numeric expressions.
C can be any single letter À to Z. It must not be the same as
a single letter numeric variable. It is initialised at value (N).
(N), (M) and (X) may take any values, positive or negative, as
long as repeated additions of (X) to (N) will reach (M). If
STEP is omitted, + 1 is assumed. NEXT C indicates last line
of the loop. It adds (X) to C and loops back if the total is less
than (M). The program loops back to the line after the line
with the FOR - TO - STEP instruction.
The FOR - NEXT loop has a fixed procedure, unlike loops formed
with conditional GOTO instructions.
We form a FOR - NEXT loop in a program like this:
10 FOR F - 0 TO 100 STEP 2
rue: Body of loop
40 NEXT F
The FOR statement initialises the loop.
0 is the start value
100 is the stop value
F is the counter variable and is initialised as Q
STEP 2 is the increment.
147
NEXT F is the last line of the loop and increments
the counter F by the STEP value.
We can also decrement the counter (decrease it). For example:
10 FOR F=100 TO 0 STEP -2
(where the decrement is 2)
The loop will be exited in the first example when Е>100 and in the
second when F«0. F will take values 0, 2, 4 .... 98, 100 in the first
case, and 100, 98 .... 4, 2, 0 in the second. Any program lines in the
body of the loop will be repeated each time the program loops.
Try these simple examples:
10 FOR F=2 TO 4 STEP 1.3
20 PRINT F
30 NEXT F
10 FOR F=4 TO -1 STEP -1
20 PRINT F
30 NEXT F
10 FOR F=-2 TO 4 STEP 2
20 PRINT F
30 NEXT F
40 PRINT
50 PRINT "F EQUALS ";F;" ON EXIT"
Convince yourself that this doesn’t work:
10 FOR F-2 TO 4 STEP - 1
20 PRINT F
39 NEXT F
The next one is an interesting example of the inaccuracies in the
computer’s arithmetic:
10 FOR Е-1.2 TO -0.3 STEP - 0.2
20 PRINT F
30 NEXTF
The only reason for using F as the control variable is that it is
convenient: FOR F can be entered just by pressing the F key twice.
You can use any letter, but it is good personal programming practice to
use the same letters consistently, and not use these for single letter
variables. ‘I’ is often used by programmers as a control variable (I for
Integer) but can be confused in program listings.
This next example uses N:
10 FORN=1TO15STEP 1
20 PRINT N,N*N
30 NEXT N
We can use the value of the control variable in calculation within the
loop. Edit STEP 1, so that line 10 reads:
107 FOR N= 1 TO 13
and run it again. STEP may only be omitted for a STEP of + 1.
148
In the program, line 10 allows N to go from 1 to 15 with a step value
of 1. That is to say, N takes the values, 1, 2, 3, 4, 5, 6, 6, 8, 9, 10, 11,
12, 13, 14, 15 each time performing the calculations within the loop.
The next program illustrates the use of different values for the step.
The value can be positive or negative, integer or non-integer. In the
case of decimal increments or decrements there is the possibility of
rounding errors if the loop is executed many times — it is therefore
advisable to use integer values for the step and divide by the
appropriate power of ten, if the loop variable is to be used in
calculations. If this were done in the program below, lines 130 and 140
would read:
130 FOR N^ 10 TO 56 STEP 7
140 PRINT N/10; TAB 8; (N/10)**2;
TAB 16; (N/10)**3 ( ^ on Spectrum)
The program calculates squares and cubes for:
a. a Seer, > 31 (line 20)
129, 115, МӘ, „аже 60 (line 70)
L, Leds X tone wwe жж 5.6 (line 130)
Once again, Spectrum owners should remember that their machine
uses the ‘up-arrow’ ( 4) rather than the ZX81’s stars (**) to represent
‘to the power of’.
5 REM "MULTILOOP"
10 PRINT "NUMBER"; TAB 8; "SQ
UARE"; TAB 16; "CUBE"
20 FOR N-1 TO 31 STEP 3
30 PRINT N; TAB 8; N**2; TAB 1
6; N**3
40 NEXT М
45 PRINT "ТҮРЕ СОМТ KEY"
50 STOP
60 PRINT "NUMBER"; TAB 8; "SQU
ARE"; TAB 16; "CUBE"
70 FOR N=120 ТО 60 STEP -5
80 PRINT N; TAB 8; N**2; TAB 1
6; N**3
90 NEXT М
100 PRINT "ТҮРЕ СОМТ KEY"
110 5ТОР
120 PRINT "NUMBER"; TAB 8; "SQU
ARE"; TAB 16; "CUBE"
130 FOR N=1 ТО 5.6 STEP .7
140 PRINT N; TAB 8; N**2; TAB 1
6; N**3
150 NEXT N
In this next program the total is represented by T which is initialised
equal to zero (line 10). Each time the program goes through the loop
the INPUT number is added to T (line 40) so that when the loop (lines
20 to 50) is exited T represents the sum of the ten numbers input. The
149
program evaluates the average by dividing the total by the number of
numbers input.
5 REM “АУЕКАСЕ”
10 LET T=0
20 FOR N=1 TO 10
30 INPUT X
40 LET T=T+xX
50 NEXT N
60 PRINT “AVERAGE =”; 7/10
This program illustrates a loop used to print a table. In this case a
heading is given (line 70) and this must be outside the loop as it is only
required at the beginning. We require all names and ages to be
tabulated so the print statement doing this (lines 140, 150) must be
within the loop. Finally, we require the average age, which is to be
printed underneath, and so the print statement (lines 170, 180) is
inserted after the loop has been completed.
10 REM "LOOPS3"
20 PRINT "THIS PROGRAM PRINTS
OUT THE NAME AND AGE OF A
GROUP OF PEOPLE AND WORKS
OUT THE AVERAGE AGE"
30 PRINT
40 PRINT "INPUT NUMBER IN GROU
5Ø INPUT X
60 LET T=
70 LPRINT "NAME", "АСЕ"
80 FOR N=1 TO X
99 PRINT "INPUT NAME"
100 INPUT N$
110 PRINT “INPUT AGE"
120 INPUT A
130 LET T=T+A
140 PRINT N$,A
150 LPRINT N$,A
160 NEXT N
170 PRINT "AVERAGE AGE-"; T/X;"
YEARS"
180 LPRINT "AVERAGE AGE"; T/X;"
YEARS"
The flowchart of a FOR - NEXT loop would be drawn like this, if we
used the standard set of symbols as presented in the unit on
programming:
150
BODY OF
LOOP
No
Yes
EXIT
So for a program like the following:
10 FOR F= 2Т0%5ТЕР.5
20 PRINT F*F
30 NEXT F
40 PRINT “ЕМГ”
the flowchart would be like this:
151
However, FOR - NEXT loops are used so frequently that this is a
somewhat inefficient way of representing a loop of this type. ‘There is
another symbol often used, although it is not a standard symbol, which
condenses all the required information. This has the form:
152
OUT OF LOOP
END LOOP
TO BODY OF LOOP
Our example program would be represented like this:
L4: Loops of Variable Length
The first value, final value and step of a loop may have any values
(including variables which may be specified using INPUT). The first
example shows a simple program which allows all conditions in the
FOR statement to be specified using the INPUT statement.
153
REM "VARLOOP"
PRINT "ТҮРЕ INITIAL VALUE"
INPUT I
PRINT "ТҮРЕ FINAL VALUE"
INPUT F
PRINT "ТҮРЕ STEP"
INPUT S
PRINT "X","X**244*X-3" [ ^ Spectrum]
FOR N=I TO F STEP 5
LET YsN**244*N-3 [ 4 Spectrum]
PRINT N,Y
NEXT N
It is important in such calculations to avoid the case where 'division by
zero' occurs. À simple
shown below:
example of how this may be done (line 40) is
REM "DIVZER"
PRINT "X","1/(X-3)"
PRINT
FOR N=-9 TO 15 STEP 3
IF М-3-0 THEN GOTO 80
LET Y-1/(N-3)
PRINT N,Y
GOTO 90
PRINT N,"INFINITY"
NEXT N
The final program in this section illustrates another way of having a
variable loop size. The operator may use this program for any number
of numbers between 1
and 100. A marker (in this case — 1) is set to
indicate when the input is complete, allowing a Jump out of the loop
(line 69). This is a ‘dummy value’ — a value not normally entered.
(N.B. DO NOT JUMP INTO THE MIDDLE OF A LOOP i.e. a
loop must always be entered from the FOR statement.)
REM "STDDEV"
LET T-0
LET 5-й
LET С-й
PRINT "THIS PROGRAM WORKS O
UT AVERAGE AND STANDARD DEV
IATION OF A SET OF NUMBERS"
PRINT
PRINT "TYPE NUMBERS ONE AT
A TIME,TO FINISH TYPE -1"
FOR N-1 TO 100
INPUT X
IF X--1 THEN GOTO 140
LET T=I+X [ ^ Spectrum]
LET S=S+X**2
LET С=С+1
NEXT N
PRINT
PRINT "AVERAGE IS ";T/C
PRINT "STANDARD DEVIATION I
S ";SQR (S/C-(T/C) **2) [ 4 Spectrum]
154
The procedure used in this program can confuse the flow of a program
and must be used with care. It is useful on occasion, but it is preferable
to have only one entry and one exit from a loop. In this program, the
loop may be exited from line 90 in addition to the normal termination,
when №100.
L5: Nested Loops
We can place one loop inside another loop, so that every time the
program goes through the outside loop, it will perform the inner loop
sequence. The inner loop must be entirely within the outer loop. Loops
are said to be NESTED one inside the other. Loops can be nested to
any depth, i.e. we can have as many loops as we wish, as long as
they’re correctly arranged.
30 FOR A=1 TO 6
40 FOR B=1 TO 3
in hs ТТТ Inner Loop
| Outer Loop
80 NEXT B |
120 NEXT A
To have a third loop correctly placed, it would have to be inside the B
(Inner) Loop, or outside the A (Outer) Loop.
Be careful to avoid crossing the loops:
10 FOR A=1 TO 6
20 FOR B=1 TO 3
80 NEXT B
Programs with wrongly arranged loops will run, without giving an
error message, but won't give you the correct answers!
To illustrate the use of nested loops, here are two programs. The first
evaluates and prints out the squares, cubes and fourth powers of the
first ten integers. Each number (N = 1 TO 10) is to be raised to the
appropriate power (E=1 TO 4). Note that the loops are correctly
nested.
20 FOR N=1 TO 10
Ee FOR E- 1 TO 4
50 NEXTE
REM "NEST"
PRINT "NUMBER";TAB 7; "SQUAR
E";TAB 14; "CUBE";TAB 21;"4T
H POWER"
20 FOR N=1 TO 10
30 FOR E-1 TO 4
40 PRINT TAB (E-1)*7;N**E; [^ Spectrum]
50 NEXT E
60 PRINT
70 NEXT N
н
Qu
You will get a printout that starts off like this:
NUMBER SQUARE CUBE 4TH POWER
1 1 1 1
2 4 8 16
3 9 27 81
4 16 64 256
The flowchart for the ‘‘NEST1’’ program, using the flowchart symbol
for FOR - NEXT loops we have introduced, will look like this:
START
We can see the sequence of operations by tracing the program.
Line 20:
Line 30:
Line 40:
Line 50:
Line 60:
Line 70:
This table uses the ZX81 symbol for exponentiation. Notice how line
40 uses the value of E to format the output.
The second example assumes that a company employs three
salesmen who keep sales figures for each week. At the end of four weeks
the company requires a summary of sales to be printed. Each salesman
S (1 TO 3) has weekly takings W (1 TO 4). Notice again that the loops
are nested within each other.
30 FOR S=1 TO 3
gon 70 FOR W=1 ТО 4
110 NEXT W
130 NEXT S
NAME WEEKi WEEK? WEEK3 WEEK4
JONES 12 16 19 13
BROWN 23 26 29 21
SMITH 31 4 6 39
10 REM *NEZTED*
20 LPRINT "NAME": ТАБ 6: "МЕЕК1
TAB i2:;"WEEKZ": TAB 207 "WEEKS
ТАЕ 27: "WEEK4"
ЗО FOR 5-1 TO 3
40 PRINT “INFUT SALESMANS NAME
- -
- -
че ча
>30 INFUT N$
EO ІРКІМТ N$;
79 FOR W=1 TO 4
SO PRINT "TYPE WEEK "М" SALE
90 INPLIT X
100 LPRINT TAB (7*W-1);X
110 NEXT W
120 LPRINT
130 NEXT $
157
Exercises
Write programs using loops to perform the operations stated:
1
Calculate the reciprocals (1/N), logarithms (LN N) and cubes
(L**3 ог L 4 3) of even numbers between 20 and 36 and print
them out in a table.
An object is dropped and the variation of distance s with time t is
given by s=4.9t*. Print a table of the distances fallen for each
second from 1 to 15 seconds.
Evaluate and print the values of ЗХ? + 4X — 7 for values of X
between 6 and 8 in steps of 0.25.
Evaluate SIN X for values of X from 0? to 360? in intervals of
10°. Remember you must convert from degrees to radians.
Print out the results in two columns.
Print a table of the discount at 5%, 10%, 15%, 20% on articles
from £100 to £200 in steps of £10.
Find the sum of all odd numbers between 39 and 75.
Find the sum of the series 1,1,2,3,5,8,... (Fibonacci) to 20
terms. (Each term is the sum of the previous two terms.)
Find all numbers less than 50 which can be written as the sum of
two squares. (e.g. 13 = 2° + 3°)
A ball is dropped from a height of twenty metres and rebounds
one-half the height on each bounce. What is the total distance it
travels? Assume the ball stops bouncing on its hundredth
bounce.
158
SECTION M: PLOTTING
M1: Plot and Unplot
The screen size is the same on both the ZX81 and the Spectrum. It is
divided into 24 x 32 character cells in the same way for printing on the
screen. The bottom two lines are reserved for use by the computer.
However, the plot screens of the ZX81 and Spectrum differ. The
principle is the same, that of dividing up the screen into small squares,
each of which can be blacked in separately, but the Spectrum has a
higher resolution plot screen than the ZX81. This means that the
screen is divided up into smaller squares (called pixels, short for picture
elements) on the Spectrum. The Spectrum has extra graphics
commands not available on the ZX81 which make use of these pixels,
some of which are mentioned in this Unit, but are dealt with fully in
Section W. The commands are also different on the two machines, so
we will describe the two separately before dealing with some of the uses
of these commands.
Spectrum users should note the principles of plotting as presented
here (even where we note that a particular process is easier using one of
the Spectrum graphics commands, since it is the principles that are
important, and can be extended to more complex tasks), and not just
feel superior to the ZX81 user, who has no access to CIRCLE or
DRAW!
On both machines each pixel is specified by X,Y co-ordinates. Thus,
on the ZX81 (0,0) is the bottom left-hand corner and (63,43) is the top
right-hand corner. There are 4 pixels in each character cell.
PLOT X,Y - blacks out the picture element (pixel) with co-
ordinates X,Y.
UNPLOT X,Y - blanks out the pixel with co-ordinates X,Y.
The PLOT co-ordinates run from 0 to 63 across the screen left
to right (X co-ordinates) and from 0 to 43 up the screen
bottom to top (Y co-ordinates).
As a memory aid, remember that X is ‘a cross’, and X before Y.
It is a simple matter to print horizontal and vertical lines. This
program plots a horizontal line across the screen:
19 FOR N = 0 TO 63
20 PLOT N,20
30 NEXT N
See if you can write a program that plots a rectangle.
Each of the character cells on the Spectrum’s screen has 8 x 8 = 64
pixels, and there are thus 176 in any column up the screen and 256 in
any line across the screen. Once again specifying each pixel with X and
Y co-ordinates, 0,0 is the bottom left-hand corner and 255,175 is the
top right-hand corner.
Whilst PLOT X,Y on the Spectrum blacks in the pixel element in
159
exactly the same way as on the ZX81, there is no UNPLOT statement
on the Spectrum. To erase the dot again the OVER 1 facility is used.
Thus, to erase at X,Y you must enter a multiple statement line.
OVER 1: PLOT X,Y - blanks out the pixel at co-ordinates X, Y
Although it is perfectly possible to plot a horizontal line to the screen
using a program similar to that used on the ZX81:
10 FOR N=8 TO 255
20 PLOT N,20
30 NEXT N
it is far simpler on the Spectrum to use the following type of
formulation:
10 PLOT 0,20: DRAW 255,0
It is also possible to get some semblance of motion. ‘The program below
moves a dot across the screen:
On the 2Х81 On the Spectrum
10 FOR N= 0 TO 63 10 FOR. N= 0 TO 255
20 UNPLOT N - 2,20 20 PLOT OVER 1; N - 2,20
30 PLOT N,20 30 PLOT N,20
40 NEXT N 40 NEXT N
It 1s possible to construct simple shapes using PLOT. Here is a ZX81
routine to draw a (somewhat stylised) dog:
10 LET X=0
20 LET Y=10
38 PLOT X,Y
40 PLOT X+1,Y-1
50 FOR N=2 TO 4
68 PLOT X+2,Y-N
70 NEXT N
80 PLOT X+3,Y-2
990 PLOT X+4,Y-2
100 FOR N=1 TO 4
110 PLOT X+5,Y-N
120 NEXT N
138 PLOT X*6,Y
140 PLOT X+7,Y-1
It can sometimes be worth remembering that the PLOT pixels are not
exactly square. The visible variation from square will depend on the
type of plotting being done, and the particular TV screen in use. It is
worth drawing what should be a square on the screen, and simply
measuring the variation with a ruler. Try running this program, and
do this for different areas on the screen, so that you can check if the
variation is constant. Note the double loop, which is often useful in
PLOT routines.
On the ZX81 On the Spectrum
10 FORF-10 TO 30 10 FOR F=10TO 100
20 FOR L= 10 TO 30 20 FOR L=10 TO 100
30 PLOT F,L 30 PLOT F,L
40 NEXT L 40 NEXT L
50 NEXT F 50 NEXT F
160
The variation from square on the screen is typically in a ratio between
1.1:1 and 1.2:1 (across screen/down screen). This means a ‘square’
that looks square will need to be 10 pixels across and either 11 or 12
pixels down.
Most PLOTting is done utilising loops. To PLOT a circle we need
to choose a suitable STEP value for a loop that runs either from @ to
360 (degrees), or 9 to 2 PI (Radians). We also have to set a centre to
give us a circle where we want it, and a radius such that it will fit the
screen. For a circle in degrees, code in this program:
On the ZX61 On the Spectrum
10 FORD=0TO360STEP10 10 FOR D=0 TO 360 STEP 2
20 LET R=D*PI/180 20 LET R=D*PI/180
30 LET X=30+20* COSR 30 LET X=120+80* COS R
40 LET Y=20+20* SINR 40 LET Y=80+80* SINR
50 PLOT AY 50 PLOT X,Y
60 NEXT D 60 NEXT D
Line 2@ converts to radians, in which all the trigonometric functions of
the computer work. Line 30 calculates the horizontal component, and
line 40 the vertical. The SIN and COS functions are multiplied by 20
(80 оп the Spectrum) to give a radius of 20 pixels. The centre is set for
the 7Х81 at pixel 30, 20, and for the Spectrum at pixel 120, 80. In
most cases, it is convenient to consider the PLOT screen to be 60 x 40
pixels (ZX81), rather than 64 x 44, in order to set scales and position
plots оп the screen, and 240 x 160 similarly for the Spectrum.
Having set the basic values, we can introduce variations within the
loop into the above program. We can calculate the radius value and get
a spiral plot. Alter the program to:
For the ZX81 For the Spectrum
10 FORD-20 ТО 360 STEP10 10 FORD-0 TO 360 STEP 2
20 LET Z = D*PI/180 20 LET Z= D'PI/180
30 LET R-Z*3 30 LET R-Z*10
40 LET X = 30 + R*COS Z 4) LET X = 120 + R*COS Z
5) LET Y=20+R*SIN Z 30 LET Y=80+R*SIN Z
60 PLOT X,Y 68, PLOT Q<, Y
70 NEXT D 70 NEXT D
Calculating additional values, all within the loop, and using the loop
values as a basis, provides complex shapes fairly easily. Alter the first
three lines of the program:
For the ZX81 For the Spectrum
10 FOR D = 0 TO 360 STEP 5 10 FOR D-0 TO 360
20 LET Z=D*PI/180 20 LET Z=D*PI/180
30 LET R= 20*SIN(Z*4) 30 LET R =60*SIN(Z*4)
RUN it. From a simple circle, we now have the basis for a polar graph
plot and can identify a scale of values for PLOTting that will fit the
screen. Similarly using parametric equations for the ellipse on the
ZX81, X goes from 10 to 50 as COS goes from - 1 to 1 and Y from 10
161
to 30 as SIN goes from — 1 to 1 round the circle. Notice this uses
radians directly (2*PI radians = 360 degrees). Spectrum plot points are
multiplied by 4.
For the ZX81
10 FOR N-0 TO 2*PI STEP PI/20
20 PLOT 30 + 20*COS N, 20 + 10* SIN N
30 NEXT N
For the Spectrum
10 FOR N =0 TO 2*PI STEP PI/180
20 PLOT 120 + 80 *COS N, 80 + 40*SIN N
30 NEXT N
Try altering the multiplication factors in line 20 for different ellipses.
Alter the STEP value to get a continuous line.
Of course, on the Spectrum a simple CIRCLE statement enables us
to achieve the same result demonstrated in our first example much
more quickly. For instance:
CIRCLE 128,88,50
will draw a circle of radius 50 pixels with its centre in the middle of the
screen. This is included with the additional Spectrum functions in
Section W. Note however that the calculated circles are more accurate
than the ones drawn using CIRCLE, but a lot slower to PLOT!
Exercises
1 PLOT the extreme corner pixels, measure the rectangle and use
the computer in command mode to calculate the proportions of a
pixel rectangle on your screen.
2 PLOT a circle, using radians directly, without a degree
conversion, with another circle, half the radius, inside.
3 PLOT a more accurate circle with allowance made for the pixels
being non-square, by altering the multiplication factors for
either COS or SIN.
4 Change the spiral routine to produce a double spiral (i.e. going
round the circle twice).
5 Experiment with the rosette producing program. Alter the
values of R in line 30 by changing the factor by which Z is
multiplied. Try Z**2 (Z^42 on Spectrum) and similar
expressions.
M2: Graph Plotting
Simple graphs may be plotted using the PRINT functions already
encountered. The following program illustrates its use for drawing a
histogram. Lines 20 to 70 allow twelve values to be input and make Z
the largest value input. Lines 90 to 150 plot out the histogram allowing
the maximum value (i.e. Z) to be 25 columns long and all the others are
drawn in proportion.
162
10 REM "HISTO"
20 DIM M(12)
30 LET 2-0
40 FOR N=1 TO 12
50 INPUT M(N)
60 IF M(N) > 2 THEN LET Z=M(N)
70 NEXT N
80 REM **PLOT**
90 FOR N-1 TO 12
100 PRINT N;TAB 4;
110 FOR L-1 TO M(N) STEP 2/25
120 PRINT "*";
130 NEXT L
140 PRINT
150 NEXT N
Result:
LKR KKK ke e e e ke e e ke e e e e e Х
2 **k*
d kk ke ke e ke e e e e e
4 kkKKKKKEK
5 ЖЖЖЖ Ж
б á kkkkkkkkkkkkkkkkkkkkkkkk
7 ж
0 kkkKKKKKKKK
О KkKKKKKK
10 ****#****@**@**%*m*@**w**w**
11 ****x*
12 *********@**@*w*
The STEP value in the program above is a SCALE FACTOR. The
use of a suitable scale factor is needed in most graphical routines. Here
is another version of a barchart program that identifies the scale factor
and uses it to multiply the values to be plotted out using the asterisks.
(The graphics characters can be put to use to draw solid bars, where
the asterisk is used here.)
10 REM *BARCHART*
20 PRINT "ENTER MAX VALUE"
30 INPUT M
40 LET SCALE-25/M
50 PRINT "ENTER VALUES (MAX 2
0) ENTER -1 TO FINISH"
60 PAUSE 150
70 CLS
80 FOR F-1 TO 20
90 PRINT AT 21,0; "INPUT VALUE ";F
100 INPUT V
110 IF V--1 THEN Goro 190
120 PRINT AT F,0; V
130 PRINT AT F,5;
140 LET V-V*SCALE
150 FOR T-1 TO INT (V4.5)
160 PRINT "*";
178 NEXT T
180 NEXT F
190 PRINT AT 21,0;" "
163
The identification of scale factors to produce the best plot possible
within the avallable X,Y values on the screen is vital in all plotting
routines. The plotted functions have to be plotted on the biggest scale
that will enable them to fit the screen. This program fits the screen
without any problem:
ZX61
10 FOR X =0 ТО 60
20 PLOT X,SQRX
30 NEXT X
Spectrum owners should bear in mind that each pixel you can PLOT
on the Spectrum is a quarter as wide and a quarter as high as those on
the ZX81. Thus, as a general rule, you should allow for a factor of four
when working with ZX81 scales, as shown in this discussion of scaling
factors. In the program above, for example, the first line would read
FOR X =0 TO 246.
The program above does not give the best illustration of the shape of
the curve, although it has the X,Y scales the same (one pixel = 1).
Changing line 20 to:
20 PLOT Х;2“5ОКХ
gives a better graph. It is obvious, in this instance, that we could
increase the scale factor — in this case the number by which we multiply
SOR X to get the Y value —to 5, and the graph would still fit the
screen.
But if we try this program (do!):
ZX61 Spectrum
10 FOR X =0 TO 60 10 FOR X-0 TO 240
20 PLOT X, X*X 20 PLOT X,X*X
30 NEXT X 30 NEXT X
we would only get a few points plotted before the computer stops with
an ‘integer out of range’ error code. It is obvious that the maximum
value in this case will be 60 x 60 = 3600 (7Х81) and 240 x 240 = 57600
on the Spectrum. So if we used:
20 PLOT X, X*X/100 20 PLOT X, X*X/400
the highest value for the Y pixel would be 36 on the ZX81, which
makes use of most of the screen. (For the Spectrum it would be 144.) In
most cases, however, it 1s not so easy to see what the scale factors
should be. We have a 44x64 screen to use on the ZX81 and а
256 x 176 screen on the Spectrum, and so in general, for positive values
only, suitable scale factors are given by:
ZX81 Spectrum
(X axis) 65 259
Largest value of X Largest value of X
(Y axis) 43 175
Largest value for Y
164
Largest value for Y
For a full range plot of a function that takes positive and negative
values, for example SIN, we have to set a scale factor which refers to
the screen available for use above and below the pixel Y value taken as
zero. To give an example, for a SIN function, taking values between
+1 and -1 we set the zero line as Y=20 (7Х81) or Y = 80
(Spectrum). We then need to find a scale value such that the Y values
vary between 20 above and 20 below this line (80 above and below for
Spectrum) as SIN varies between + 1 and - 1. Again, it is obvious that
we need to use a line like:
2Х81 Spectrum
20 PLOT X, 20 + 20*SIN X 20 PLOT X, 80 + 80*SIN X
To get a single full range curve we need X to vary from 0 to 2PI
radians, so we can use:
10 FOR X -0 TO 2*PI STEP 2*PI/60
20 PLOT X, 20 + 20 *SIN X [80 + 80 *SIN X on Spectrum]
3 NEXT X
for full screen use. (Remember 2PI radius = 360°.)
Up to now, although you have been told about the co-ordinates of
the PRINT and PLOT screens, we have treated the use of PRINT and
PLOT as two separate areas.
Since the PRINT and PLOT co-ordinate systems refer to the same
screen, the two may also be used in concert, but care must be taken.
Confusion is likely to arise between the numbering systems, not so
much in the numbering across the screen, but in the Y plane, where
pixels count 0-43 (@-175 оп the Spectrum) upwards, and the print lines
0-21 downwards. Pixels are coded X,Y, across and up, print positions
L,C, down and across. The screen grids for printing and plotting are
reproduced here for both the ZX81 and Spectrum.
165
THE ZX81 PRINT AND
PLOT SCREEN
You cannot PRINT or PLOT
on the bottom two lines.
«—— Lines
An example: this is
Columns —— the pixel (57,32)
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
x 48 | 50 | 52
Pixel x-coordinates PHT
Pixel y-coordinates ----ь
166
An example: this is
the pixel чыш
|
=
E
=
О
Q
ESI
q — s3}2uIp1009 Á |axid
6/1. ¿9L 861 161 ЕРІ SEL 721 GLL Lit EOL 96 ZB 62 14 БӨ SS Zh ФЕ IE EE Gt и
891 091 ZSL vti 961 821 001 Zit VOL 96 88 08 22 v9 95 BH OF ZE vC 9 8
0
38
еу ~
<+ š
бәш| OM} uuolloq eu) uo |
1014 10 LNIHd Aijeuuou 1ouueo под
N33439S 10 ld
'? Іміна WNYLOAdS JHL
Pixel x coordinates ——— р>
It is useful, when both PRINTing and PLOTting on the screen, to
work with one screen grid first, and then add the other grid. As an
example, consider graph titles. We could, to get a title for a printout of
a graph, use a direct command: PRINT ‘‘GRAPH OF
Y = X**2/100’’, then use COPY, BREAK the COPY routine after the
first lines printed, then PLOT the graph with our program and COPY
that, but it’s not very elegant. We want the title on the screen with the
plotted graph. We can first set the PLOT routine, for example:
ZX61 Spectrum
10 FOR N=0 TO 60 10 FOR N-0 TO 250
20 PLOT N, N*N/100 20 PLOT N, N*N/400
30 NEXT N 30 NEXT N
By inspection, after RUNning the routine, we can add a title where it
will not interfere with the PLOT.
40, PRINT AT 0, 35: “27
50 PRINT AT 1,0; “Y =X 7100
This gives us a screen with everything on it, with the bonus of using
standard notation for X°, not the BASIC’s ** (fon Spectrum)
notation. A different function might require the PRINTed strings to be
placed elsewhere.
Exercise
Write a program that will calculate the pixel co-ordinates of any
PRINT square (character cell). Input L and C (for Line and Column),
with suitable prompts erased by an empty string, and output
“Piel” s Х; 4)”; Ү; 16 top right’’, etc. For the ZX81, output the four
pixels in any specified character cell. For the Spectrum, output the
X,Y co-ordinates of the four corner pixels.
168
SECTION N: SUBROUTINES
N1: Subroutines
A subroutine im BASIC is a program module performing an allotted
task and is entered using a GOSUB statement. The section of program
Is completed and exited by a RETURN statement which sends the
computer back to the line following the GOSUB statement. A
subroutine must only be entered via a GOSUB statement and exited by
a RETURN statement.
Two instructions are used to create subroutines.
GOSUB (line number) - transfers control to the specified line
number
RETURN —leaves subroutine and returns
control to the line immediately after
the GOSUB instruction which
transferred control to the subroutine.
Spectrum users have probably noted that their machine prints GO
SUB with a space.
Here is an example of the program structure for these instructions:
IBS ,..
110 GOSUB 500 --------(1)
Таб ...
TO uw
140 GOTO 600
520 REM *SUBROUTINE*
(3) 5318 vs
520 ... dy (4)
539 wns
540 RETURN
600 STOP
(1) GOSUB - goes immediately to line indicated (500)
(2) Continues program (lines 500-540) until RETURN reached
(3) Program returns to line 120 (line immediately after GOSUB
statement).
(4) Itis vital to ensure that a subroutine is not entered accidentally
when writing the program. Note that line 140 does this by using
a GOTO statement to bypass the subroutine. Line 600 may
continue the program, or be a statement such as REM*END
OF PROGRAM”. It is a useful practice to end a program at the
highest line number, which indicates successful completion of
the whole program. The alternative, stopping the program with
a line 140 STOP, could also be used.
169
Subroutines are often used for repeated procedures and may be
thought of as separate program structures:
MAIN ROUTINE SUBROUTINE
100
114 GOSUB 500—~>|500 REM SUBROUTINE *
120 -&——— 510
130 520
14) GOSUB 500— 1530 REM * END OF SUBROUTINE *
150 =< 540 RETURN
160
The computer stores the line number of the GOSUB instruction
(whereas it doesn’t with a GOTO). The RETURN instruction
transfers control back to the line number after the /atest GOSUB. As
shown above, this means we can enter a subroutine repeatedly in the
course of a program.
N2: Subroutine Example
The example program given below evaluates the circumference and
area of a circle, and has a subroutine to round the results to two
decimal places. The program works as follows:
(1) Calculates the circumference (line 40), and makes this figure
equal to variable Z (line 45), which is the variable the subroutine
will round.
(п) Enters subroutine (line 50).
(ш) Corrects answer to 2 significant figures (subroutine lines
200 — 230), and returns with rounded value of Z to line 60,
which:
(iv) Prints out circumference (line 60).
The same procedure is then repeated for the area, the subroutine being
entered (called) again in line 90. Lines 200 to 23@ of the program are
then executed again, but the RETURN statement this time returns
control to line 100 (the next line after the last GOSUB statement).
It is essential to have line 110, which prevents the subroutine being
entered accidentally when the calculation is complete.
10 REM "CIRCLE"
20 PRINT "TYPE RADIUS"
30 INPUT R
40 LET C=2*PI*R
45 LET Z=C
50 GOSUB 200
60 PRINT "CIRCUMFERENCE IS ";2
70 LET A=PI*R**2 [ ^ Spectrum]
80 LET Z=A
90 GOSUB 200
170
100 PRINT "AREA IS ";Z
110 GOTO 3609
120 REM *MUST NOT ENTER A SUBROUTINE
EXCEPT BY A GOSUB*
200 REM **SUBROUTINE TO CORRECT TO
TWO DECIMAL PLACES**
210 LET Z=INT (100*(Z4.005))
220 LET Z=Z/100
230 RETURN
240 **END OF SUBROUTINE**
300 REM **END OF PROGRAM**
The second example is a program to evaluate the sum of the series
1 4 1/2! +1/3! +.. 41/10! to 6 decimal places. (The exclamation
mark (!) means ‘factorial’. Factorial 5 (5!) is 5x 4x 3x2x 1, etc.).
In this program there are two separate subroutines. The subroutines
are both entered repeatedly. The first is to evaluate the factorial and
the second corrects the answer to 6 decimal places. Although it is not
essential to use subroutines in such a program it does improve the
structure and make it considerably easier to follow the sequence of
operations.
19 REM "FACTORS"
40 LET 5-й
50 FOR 2-1 TO 10
60 GOSUB 200
70 LET T=1/X
99 LET S=S+T
100 PRINT Z;" TH TERM IS ";T
118 NEXT Z
120 GOSUB 300
130 PRINT
140 PRINT "SUM OF SERIES ";V
150 GOTO 400
200 REM **SUBROUTINE FACTORIAL**
210 LET X=1
220 FOR N=1 'TO Z
230 LET X=X*N
240 NEXT N
250 RETURN
300 REM **SUBROUTINE 6 D.P. **
310 LET V=INT (1E6*(S+5E-7) )
320 LET V-V*1E-6
338 RETURN
400 REM **END**
Results on screen:
TH TERM IS 1
ҮН TERM IS 0.5
TH TERM IS @.16666667
TH TERM IS .041666666
TH TERM IS .083333333
; - 0013888889
TH TERM IS .0001964127
TH TERM IS .000024801587
TH TERM IS 2. 7557319Е-6
TH TERM IS 2.7557319E-7
SUM OF SERIES 1.7182862
= оо - OY Ut i» Q N =
<
=
"3
г
=
=
ні
о
-
171
Trace the program through for the first two terms to ensure that you
can follow the flow.
N3: Nested Subroutines
This technique is similar to nested loops in that a subroutine is entered
from another subroutine.
In the simple example given the program enters the first subroutine
(line 300) and from within this calls up the second subroutine (line 320
calls up subroutine at line 400) which is completed and returns (line
420) to the first subroutine which is then completed. See the diagram
below of the program flow.
Hand trace this program to discover the result of running it. (N.B.
This program is only used to illustrate nested subroutines and the
calculation carried out clearly can be done more easily without their
use. )
10 REM “SUBROUTINE1"
20 LET M=5
30 GOSUB 300
40 PRINT M
58 GOTO 569
300 REM ****1ST SUBROUTINE****
310 LET М=М+1
320 GOSUB 400
330 REM **RETURN TO MAIN PROGRAM**
340 RETURN
350 REM * k k k oo k k # k k k k k k k k k k k k Kk
400 REM ****2ND SUBROUTINE****
410 LET M=M* (M+1) **2 [ # Spectrum]
‘20 RETURN
430 REM k k k k k k k k k k k k k k k k k k k k k k k
500 PRINT "END OF PROGRAM"
The diagram illustrates the procedure in the above program for two
nested subroutines.
30 GOSUB 300
40
50 сото 500
(7) 360
33$ sans
320 GOSUB 400
oo peas
34@ RETURN
Е"
(3)
35D ....
(5) 49D ....
410 ....
420 RETURN
430 owes
(1) Subroutine 1 is called at line 30.
Enter first subroutine at line 300.
(2) Start executing first subroutine.
(3) Subroutine 2 is called at line 320.
Enter second subroutine at line 400.
(4) Execute second subroutine.
(5) RETURN at line 420 returns program to line 330 (line
following GOSUB call).
(6) Continue execution of first subroutine.
(7) | RETURN at line 340 returns program to line 40 (line following
GOSUB call).
(8) Statement to avoid entering subroutines accidentally.
The second example is typical of a computer games program. The
nested subroutine ensures that the computer’s move is printed out each
time before the player makes his move.
10 REM "NESTSUB"
20 REM **PART OF GAMES PROG**
30 LET х-3
40 GOSUB 600
45 PRINT
50 PRINT "YOUR MOVE WAS ";M
60 PRINT "COMPUTERS MOVE ";X
70 STOP
600 REM **SUBROUTINE PLAYER**
610 GOSUB 700
620 PRINT "YOUR MOVE?"
630 INPUT M
640 RETURN
700 REM **SUBROUTINE COMPUTER**
710 PRINT "COMPUTERS MOVE ";X
720 RETURN
Note that it would make no difference if the nested (called from a
subroutine) subroutine were to start at a lower line number than the
subroutine which called it. Subroutines are always discrete program
modules, wherever they are located in a program.
N4: Recursive Subroutines
A recursive subroutine is a subroutine that calls itself. This facility 1s
not available in some versions of BASIC used on other computers. For
some purposes this can be a very useful program structure. From
within a subroutine, a GOSUB instruction is used to transfer control so
that the program re-enters the subroutine. The computer stores each
GOSUB call, with the line number to RETURN to, just as if the
GOSUB call had been made to a different subroutine. The RETURN
instructions are executed in reverse sequence to the order in which the
GOSUB instructions were encountered.
The example program below evaluates the factorial. of any number
N, input as an integer less than 30. First the program, then the
explanation:
173
20 КЕМ
20 PRINT
30 INPUT М
"RECSUE"
"TYPE NUMBER<20"
40 IF М>20 THEN GOTO 200
S50 БОЦЕ 100
80 PRINT F
20 КЕМ
20 REM жЕ € € 93€ зен 3€ 9€ ж
1 THEN GOTO 140
100 REM *#+##SUBROLUT INE ++
110 IF N <>
120 LET F=1
iso GOTO 180
140 LET NzN-1
150 GOZE 100
160 LET F=F*(N+1)
170 LET N=N+1
120 RETURN
135 REM **##*# END SUE жж
190 КЕМ
200 РЕІМТ
“OBEY INSTRUCTIONS, РЕ
ESS RUN AND NEWLINE/ENTER"
210 КЕМ **END#*
To help us decipher the program flow, we can insert PRINT
statements and add a counter, in order to code the GOSUB and
RETURN instructions with a number to indicate the sequence in
which the recursive calls are performed. Add the following lines to the
program:
5 LET C=90
35 PRINT N
45 LET C=C+1
55 PRINT “RETURN TO MAIN
РКОСКАМ”
145 LET C=C+1
146 PRINT “GOSUB CALL ”;С
147 PRINT “N=";N
155 PRINT''RETURN CALL “G
156 LET C=C-1
165
175
PRINT “Е=”;Е
PRINT “N =’’:N
(sets counter to count
GOSUPB calls)
(prints first value of N)
(first GOSUB call from main
program)
(final RETURN executed)
(increments counter each
time GOSUB is used
recursively)
(prints each time GOSUB is
used recursively)
(value of N before each
recursive GOSUB call)
(prints each RETURN call as
made, corresponding to the
GOSUPB call of the same
number)
(decrements counter as each
RETURN is executed)
(value of F at each stage)
(value of N at each stage)
Then run the program for N = 3. The resulting ‘machine trace’ screen
display 1s:
174
3
GOSUB CALL 2
N=2
GOSUB CALL 3
N=1
RETURN CALL 3
F=2
N=2
RETURN CALL 2
F=6
N23
RETURN TO MAIN PROGRAM
6
If we draw up a trace using the data from this display (as below), we
will see that the GOSUB at line 150 is executed for each value of N from
1 to N. The RETURN calls are then made for each value from 1 to N,
calculating F each time (line 160) and incrementing N (line 170), so
that the value of factorial N is calculated as 1x2x3...x N. The
flowchart of this program is quite simple, but the algorithm is not clear
unless the sequence of GOSUB and RETURN calls is understood.
The computer stores each GOSUB call in sequence in a portion of
memory called the GOSUB stack, and each RETURN instruction
removes one of these stored GOSUBSs, passing control to the line after
the GOSUB call. Confusion is possible with recursive subroutines
because the RETURNS are made to the same program line each time
(line 160 in this case).
“RECSUB”’ - Trace јот N = 3:
50 GOSUB(1)
60
100 N-3 N=? N=1
110 F
120
130
140 Nš2 Nš!
150 GOSUB(2) GOSUB(3)
160
E
170
180 R
F = 1*9 F v 2%3
N=2 N =3
TURN(3) RETURN(2) RETURN(1) - (To main program)
175
Flowchart - ‘‘RECSUB”’
START
©) (2)
F=F*(N+1)
RETURNS TO LINE
RETURN AFTER LAST GOSUB
CALL.
В)
176
Notice that line 130 passes control to the RETURN statement of line
180. Check for yourself that line 130 could be a RETURN instruction
and the program would still run correctly. This is likely to result in a
less visible flow in the program, however.
The next program has a subroutine (starting at line 100) which calls
itself in line 150. As for the previous program, insert suitable PRINT
statements to print out the values of the variables and the number of
GOSUB calls made. Hand trace the program for suitable integers, e.g.
15 and 25. The program evaluates the highest common factor of the
two numbers input. Note that in this case there are no processing
statements between the GOSUB call in line 150 and the RETURN
instruction of line 160. The sequence of RETURNS will be executed
by control going repeatedly to line 16@ (the line after the GOSUB call),
which does the next RETURN, until the last stored GOSUB is
encountered, which will pass control back to line 5@ of the main
program.
5 REM “HCF"
10 PRINT “TYPE ‘TWO POSITIVE INTEGERS"
20 INPUT M
30 INPUT N
49 GOSUB 100
50 PRINT "ANSWER IS";P
68 GOTO 220
100 REM **SUBROUTINE**
110 LET P=N
120 LET N-M-N*INT (м/м)
130 LET M=P
140 IF М-й THEN GOTO 160
158 GOSUB 100
210 REM
220 REM **gND**
N5: Computed Gosubs
The line number N in a GOSUB N program instruction may be a
computed expression: it is permissible to have any expression as the
numeric value for a line number.
We can make use of this in programs where we want to give the user
some options of operations. Since we would write the program with
these options as subroutines, a suitable choice of line numbers can
allow us to present a menu to the user. Here are two (useless) examples
to illustrate the principle:
1) 10 PRINT "MAIN PROGRAM"
20 PRINT "INPUT 1 OR 2"
30 INPUT X
40 GOSUB Х%100
50 PRINT "MAIN PROGRAM ENDS"
69 PRINT "NOW BACK TO MENU"
70 PRINT
80 GOTO 10
177
100 PRINT "FIRST SUBROUTINE"
110 RETURN
200 PRINT “SECOND SUBROUTINE"
210 RETURN
2) 10 REM *NESTED SUBS FOR MENU**
20 REM **INITIALISE MENU GOSUB**
30 LET MENU-14009
40 REM **MAIN PROGRAM**
50 PRINT "MAIN PROGRAM"
60 REM ....
70 PRINT "NOW TO MENU"
80 PRINT
90 GOSUB MENU
100 PRINT "MORE MAIN PROGRAM"
118 PRINT "MENU OR END PROGRAM?"
120 PRINT "INPUT M OR E"
130 INPUT NŠ
140 IF N$-2"M" THEN GOSUB MENU
150 GOTO 9999
1000 PRINT TAB 3;"MENU"
1010 PRINT ,,"1. OPTION 1",,"2.
OPTION 2"
1020 PRINT "INPUT 1 OR 2"
1030 INPUT M
1040 GOSUB (M*1000)+100Q
1050 RETURN
1100 REM ****SUB l*****x*
1110 ВЕМ k k k k k k k k k k k k k * k
1120 PRINT "SUB 1 COMPLETED"
1130 PRINT
1140 RETURN
2100 REM ****SUB 2******
2110 REM £ k k k k k k k k k k k k k k
2120 PRINT "SUB 2 COMPLETED"
2130 PRINT
2140 RETURN
9999 STOP
Notice the use of a variable ("MENU") to hold the line number
(1000) of the Menu subroutine (Lines 20 and 30). This technique can
be useful as a mnemonic in longer programs, and can help the user
identify which program module has been called.
This technique can be combined with the use of INKEY$ to give an
instantaneous jump to the required subroutine. The program waits for
a key to be pressed and then jumps to the required subroutine.
10 PRINT "PRESS 1 FOR SUB 1","
PRESS 2 FOR SUB 2"
20 IF INKEYS=""
30 LET AS=INKEYS
THEN GOTO 20
35 IF А5-"1" OR А5-"2" THEN СО
TO 60
40 PRINT "KEYS 1 OR 2 ONLY PLE
ASE"
50 GOTO 10
60 GOSUB VAL А5%100
70 PRINT "BACK TO MENU"
80 GOTO 18
178
PRINT "********k*kkkkkk"
PRINT "SUBROUTINE ONE"
PRINT "*********X**x"
RETURN
PRINT "soo x de e e e e x n
PRINT "SUBROUTINE TWO"
PRINT "s***k*kkkxkkx"
RETURN
Spectrum users should replace line 20 with
20 PAUSE Q
N6: Subroutine Use: Example
As an example of the use of subroutines, here is a guess-the-number
game. The program has three subroutines, one to get the number (lines
150 — 190), one to check the guess (lines 210 — 300), and one for the
success message (lines 350 — 410), which sets the marker MARK to tell
the main program, which is the loop between lines 50 and 140,
whether the number N (computer's number) is the same as G (the
player's guess). This defines whether the success subroutine has been
called as a result of the conditional test in line 110.
22
10
20
30
REM "GUESSNUM"
LET MARK =0
LET TRIES=0
PRINT “GUESS MY NUMBER, "++,
“NUMBER: IS BETWEEN 1 AND 99"
(M9 е „ ts
cC uy < ord
-— — ЫҢ М. !.
Же
_
—
“ІЛ
-- ұл pe bh FS p
I 63 3 Кә ка 0 CY oo
ез»
йу,
—
1
—
i+ p» pee de dex
ooo C on
oO ch <s C)
!
о
) LE" TR
КЕМ жж СЕТ NUMBES жж
ces LIE
FO
ES=TRIE'S+1
PRINT ss “ENTER YOUR GUESS"
INFLT
Ж
oe” Ramee ane
ӘЕМ жж GOSIP CHEE ж
DOSJE ооо
REM жж GOSUB SuUmTE Ss жж
IF DIFFzO THEN SOSE 280
REM x CHECK MARK жж
IF MARK=! THEN GOTO Soo
БЕМ x LOOP BACK жж
GOTO So
ES cA каға
REM XX%3 3333333333 3333 XE CE
REM ** БЕТ NUMBER SUE: жж
MEM 333 3 3 09 Ж € 0€ 303€ 9€ EHH
LET N= INT С REND sv9541
RETURN
REM жж ENDS UE: xx
REM X3 OX X АХ ЖАЖА EE
REM
БЕМ 3636363 ЖЖ Жы HEH
REM жж HECK SUE xXx
REM 33 33 09€ 3 0€ ЖҰ EE EH
230 LET DIFF= ABS (G-N)
IF DIFF250 THEN PRINT 9a "FR
EEZING"
179
250 IF DIFF>25 AND DISF <= 50 T
HEN PRINT 95 "COLD"
260 IF DIFF>10 AND DIFF <= 25 T
HEN PRINT у» "xWARIME" |
270 IF DIFF>4 AND DIFF <= 10 TH
EN PRINT +," ж НОТ жж "
280 IF DIFE>O AND DIFF <= 4 THE
N PRINT ss" жж #BCILING# жы"
290 RETURN
700 REM жж END CHECESZLUE xx
210 REM ххх хз ЖЖЖ ЖЕК
220 REM
240 REM 33 CC 30 KHER HEHE HEH
GEO БЕМ жж зи Sup ++
SEQ REM хажы ғ HH ED
370 PRINT AT 9.95; "%%%%%7%%%7%%";
TAB 5: "$ SUCCESS %": TAB Si "$5
HEEE ESE"
380 PRINT АТ 10%5: "ІТ TOOK “ITR
IES?" TRIES. “
390 LET MARK =1
400 RETJEN
410 REM жж END SUMCESS Sie жж
420 REN X3X33X3 939 0 HE EK EE Y
430 СЕМ
470 REM жж ЖЖЖ
490 REM жж END/RESUN MOD xx
495 БЕМ 3*3 9 X 3 X 3 30 Ж Жы
200 PRINT ,$4"ANUTHE SO? INPUT
Y OR N"
SiO INFUT A$
CL
930 IF A$z"Y" THEN GOTO АО
940 PRINT +. "Ok. BYE"
wool STOP
Se REM xx xx END хх жж
The structure of the program is thus:
Module 1:
1. Initialise success marker MARK and variable to store number
of guesses made (TRIES)
2. Print Instructions
3. Call GET NUMBER Subroutine
Module 2 (Main program loop):
1. Increment TRIES
2. Input guess
3. Call CHECK Subroutine
4. Check if Guess equals Number. If it is, then call SUCCESS
Subroutine
5. Check marker. If Success subroutine has been called
(MARK = 1), then GOTO END/RERUN module
6. Loop back to Input guess again (1)
180
Module 3 (GET NUMBER Subroutine):
1. Define random number 1-99 as number N
2. Return
Module 4 (CHECK Subroutine):
1. Set variable DIFF equal to ABS difference of guess and number
2. Check value of DIFF, print appropriate message
3. Return
Module 5 (SUCCESS Subroutine):
1. Print success message, number of guesses made
2. Set MARK equal to 1
3. Return
Module 6 (END/RERUN module):
1. Print prompt for input
2. Input response to Another go? (A$)
3. If replay required (A$ = ‘‘Y’’) then GOTO Module 1,3
4. If A$ not “Ү” then print end message
5. Stop
Notice that (although this is a program that has been modularised
rather artificially to demonstrate the principles in a short program) the
program consists of an introductory section, then a main program loop
with both conditional and unconditional calls to subroutines, within a
short main program loop. This makes the structure of the program
clear, and minimises the use of GOTO statements, which would be
required in profusion if the program were written in a linear, rather
than modular fashion. It is perfectly possible to write the program in
this linear manner, but the structure will not be as visible.
You should also note that the END/RERUN module is not a
subroutine, but uses GOTO to pass control to this section from the
main program, with a conditional GOTO to pass control back to the
main program if required. Conditional GOTOs аге preferable
program structures to unconditional GOTOSs, and whilst the END
module could be a subroutine, RETURNing to the main program
loop, further conditions would need to be inserted to pass control to
Module 1 for a new number to be defined. The subroutine would also
need to be exited by а GOTO for the program to stop. There is another
solution, however, involving a nested subroutine, which we will set as
an exercise.
Exercises
1 Rewrite /GUESSNUM"' with the END/RERUN module as a
subroutine. The procedure should be as follows:
END/RERUN SUB
i. Prompt for player input, and get response, as before.
181
п. If RERUN not required, bypass 3 апа 4 below, by a GO TO
the RETURN line.
ш. GOSUB to GETNUMBER subroutine. This is a nested
subroutine. The new value of N will be set by this operation.
iv. Re-initialise TRIES as 0 and MARK as 0.
v. Return.
The main program loop is then returned to. The main program
must then test whether it is to exit (rerun not required) or
continue (new game started). We could set another marker to
test this, but in effect we have done this by re-setting MARK ifa
rerun is required.
Rewrite the main program loop, so that on return from the
END/RERUN subroutine, the program loops back only if
MARK = 0. If MARK = 1 then the program will not loop back
and you can either insert a GOTO to bypass all the subroutines
to an end program procedure, or STOP the program before the
subroutines.
Insert an additional subroutine which prints 1;‘‘ST’’,2;
“ND”,3;*°* RD”, and then “ТН” for other numbers into the
“FACTORS” program (Unit N2).
Write a program which determines how many rolls of a die are
required to produce a total score greater than 100. Use
subroutines to produce the random numbers for the die rolls and
to print out the results.
Let the computer choose a four digit number with no two digits
alike. You try to guess the number chosen. The computer
indicates H (too high), L (too low) or R (right) for each digit in
turn and determines how many guesses are required to get the
correct number. Use subroutines to create the number, input
the operator's guess and give the response to each guess.
182
PART THREE
ADVANCED BASIC PROGRAMMING
ТАРЫ s ДАЧ
ОЛА мМАЯООЯЯ MEAN LOW ATTO А
SECTION O: PROGRAMMING METHODS II
O1: Résumé
Before we enter the arena of advanced BASIC programming let us
recap on what we have examined and accomplished so far.
The method to design the solution or algorithm to a computational
problem using ‘top down’ analysis has been explained. We have seen
how to break our problem up into sub-problems which form our
program modules (using tree diagrams). We know how to describe the
algorithm in concise English sentences that we call pseudocode and
how to determine and illustrate the flow of control in the problem
solution by drawing a flowchart. When designing our solution we
recognise the need to use the fundamental programming tools of:
(1) decision making
(п) branching as a result of decisions
(iii) direct transfer from one point in the algorithm to another
(iv) repetition
These control structures, as they are called, which are present in all
computer languages, have been discussed in some depth, together with
other important BASIC language fundamentals. The techniques of:
(1) decision making
(п) numeric processing
(iii) character handling with strings
(iv) looping through counting and condition testing
(v) handling of output by printing and plotting
and the realisation of modular techniques in programming by using
subroutines have all been covered.
WHAT'S NEXT?
We must now consider the second phase of the programming
method - producing the program itself.
It 1s important to do so at this stage in the book, so that our
programming tool kit is complete enough to investigate and use the
more sophisticated information handling facilities to be introduced
later in this section:
(1) logical operations on data
(1) character codes
(uni) moving graphics
(iv) graph plotting
(v) constructing and searching lists and data arrays
(vi) how to sort information into order
Once these skills have been mastered our complete programming
expertise can then be applied to real applications.
Let's now see in this section of the text how to code our algorithms
into BASIC language programs, and then debug, test and document
them.
185
Further important design rules will be given, and finally a summary
of our complete programming method will be provided with a
flowchart and worked example.
O2: Producing the Program
We now consider the method by which a well designed, tested and fully
documented program is produced.
Given our algorithm - which we have written out in steps in a
description we call pseudocode — together with our flowchart — which
shows how the steps of the solution are combined in sequence for the
computer to solve the problem - we must now:
1. CODE THE ALGORITHM IN SINCLAIR BASIC
2. DEBUG AND TEST THE PROGRAM
3. DOCUMENT THE PROGRAM
O3: Coding and Design
CODE ON A ONE TO ONE BASIS
If the description of the algorithm is correct then coding on an almost
one to one basis from statements in the pseudocode or the flowchart is
possible. If you cannot code from the flowchart or pseudocode then
further refinement of the algorithm is necessary.
Pseudocode descriptions in formal mode of the BASIC language
control structures for decisions and loops are given later in this section.
You will notice that the description itself is indented and concise, with
the terms almost the same as BASIC statements. This is not unusual as
BASIC was designed to do this very thing and 1s English-like in its
syntax.
To be able to code at all you must of course:
KNOW THE BASIC LANGUAGE AND ITS RULES
Hopefully it is the right language for the job. On the ZX81 and
Spectrum you don't have much choice! Actually it is a question of ease
of programming specific applications that generates different
languages. Most things can be done in BASIC, although perhaps not
efficiently or elegantly. It is often useful to identify the kind of
processing that will be required. When designing the algorithm
consider whether the problem is a scientific or a business application,
whether extensive calculations will be performed or large amounts of
list processing done, whether the data is extensively numeric or string
and whether the program will be interactive with much user dialogue.
When coding, avoid spelling and formatting mistakes. Sinclair
BASIC is powerful in that it is one of the few available single keystroke
186
BASICs, hence you cannot make spelling mistakes on instructions or
commands because the whole instruction is keyed in at once. However,
mistakes can still be made when assigning variable names and in
PRINT and REM statements.
DEFINE AND CONTAIN EACH MODULE
WITH REM STATEMENTS
For example:
100 REM * SORT MODULE *
200 REM * THIS MODULE SORTS STRINGS *
500 REM * END SORT *
TERMINATE YOUR PROGRAM PROPERLY
You may have noticed that Sinclair BASIC does not need a special
end-of-program statement. We can, however, put one in using a REM
statement. For example:
500 REM * END OF PROGRAM *
Тһе 7Х81 and Spectrum do not process but only note REM
statements. When the above line runs, the program will finish
elegantly with a 0/500 message.
We can also stop a program with the STOP statement. Main
modules should finish like this with subroutines programmed at higher
line numbers terminated with a REM * END * statement. When
terminated with STOP a message 9/line number (a 9 Stop (Line
number): 1 statement on Spectrum) will be given.
REM * NAME OF PROG *
10 REM * MAIN MODULE *
20 GOSUB 500
30 STOP
40 REM * END MAIN *
500 REM * SUBROUTINE *
600 RETURN
700 REM * END SUBROUTINE *
800 REM * END OF PROGRAM *
We could also use a GOTO 800 at line 30 to terminate execution on
the last program line.
ALWAYS CODE ACCORDING TO THE LOGICAL ORDER
OF PROCESSING
This is usually ensured if you code from a flowchart, with your
187
flowchart structured into modules, i.e. flowchart groups for the
modules in the program.
Take care with the control structures and avoid unnecessary
branching, especially with GOTO instructions. Try to make your
programs both readable and efficient — but first make them readable!
USER FRIENDLY PROGRAMS
Design your programs with the user in mind - and that includes you!
Directions to users should be concise and as few as is necessary, both in
the program and in the user guide if your program is large enough to
merit one.
Where the user needs a number of instructions to operate the
program then these can be built into an optional ‘help’ module or
subroutine.
100 REM * USER INSTRUCTION *
110 REM * DIRECTS USER TO HELP SUBROUTINE *
120 PRINT “ FOR INSTRUCTIONS TYPE HELP
OTHERWISE TYPE C "
130 INPUT A$
140 IF A$ - *HELP''THEN GOSUB 1000
150 REM * END USER INST *
1000 REM * HELP SUBROUTINE *
1200 RETURN
1210 REM * END HELP *
Users usually require to know:
~ how to run the program
— what form of input data is required
— what output is produced
Your program should check on the range and type of input data. If the
input data is out of range or incorrect the program should not stop with
an error, but continue with a message to input correct data.
After you have designed a program to do a specific task it may be
worthwhile to change it to be as general as possible — i.e. do several
similar tasks. As you become more skilled and confident in
programming you will be able to generalise and write a subroutine that
enables users to select options from a menu. This is exactly similar to
the exercise you have seen in multiple decision structures. See the
"CASSFILE'' program in Section V, for a ‘‘menu-driven’’ program.
More “‘user-friendly’’ tips are given in the section on documentation,
and some useful routines in Unit V2.
188
DESIGNING PROGRAM LAYOUT
You must make your program readable. The program design will be
modular and contain specific identifiable segments, subroutines and
modules. These should be labelled in the design of the algorithm and
transferred in the coding process.
(1) EACH MODULE SHOULD BE TITLED AND LABELLED
TO INDICATE ITS FUNCTION. FOR EXAMPLE:
10 REM “AVERAGE”
20 REM * PROGRAM AVERAGES ANY NUMBERS
INPUT *
3 REM *
40 КЕМ * USER ROUTINE *
50 REM * CHOICE OF NUMBERS INPUT *
60 PRINT “HOW MANY NUMBERS DO YOU WISH
TO АУЕКАСЕ”
70 INPUT N
80 DIM A(N)
9) REM * INPUT ROUTINE *
100 REM * NUMBERS INPUT TO ARRAY *
110 PRINT “INPUT NUMBERS"
120 FORI=1TON
130 INPUT A(I)
140 NEXT I
150 REM
160 REM * PROCESSING ROUTINE *
170 REM * COMPUTES AVERAGE *
180 LET SUM-0
199 FORJ=1TON
200 LET SUM = SUM +A(J)
210 NEXT J
220 LET AVERAGE - SUM/N
230 REM
249 REM * OUTPUT ROUTINE *
250 PRINT “THE AVERAGE OF"
260 FOR K=1 TON
270 PRINT A(K); ”’;
280 NEXT K
290 PRINT “IS ”; AVERAGE
300 REM
310 REM * END AVERAGE *
(2) DESIGN YOUR PROGRAM SO THAT RELATED
STATEMENTS ARE TOGETHER
For example, input — processing — output statements:
() All input statements will be at the beginning of a simple
sequential program, processing in the middle, and
output normally at the end.
189
(3)
(4)
(9)
(üu) For a modular program, input, processing and output
routines will be separate modules or groups of statements
within a single module.
(ш) Subroutine modules will usually be placed separately at
the end of a program.
INSERT REM STATEMENTS BETWEEN PROGRAM
MODULES AS SEPARATORS
Program modules are then easily identified. Use blank REM
lines or lines of asterisks.
PLAN YOUR PROGRAM LAYOUT BEFORE CODING
The printed listing of your program is important. Choose a
maximum line width. Break longer lines into shorter ones in
REM statements by using spaces. Compensate for overrun. For
example:
10 REM * AAAAA
AAAAA
AAAAA *
You will not be able to do this with other BASIC statement lines.
YOUR LAYOUT SHOULD TRY TO REFLECT THE
MODULAR STRUCTURE OF YOUR PROGRAM
190
Indented statements are not possible on the ZX81 or Spectrum,
unfortunately!
DESIGNING PROGRAM OUTPUT
For the user the output is the most important part of the program.
Take time planning it. The output instructions in Sinclair BASIC are:
PRINT, PRINT AT, PLOT, LPRINT, COPY, TAB, plus graphics
commands.
() RESULTS SHOULD BE OUTPUT WITH RELATED
ITEAL
Label all your numerical output:
єн. 1974 £5678.65
instead of 1974 5678.65
e.g. AVERAGE AGE OF BOYS IS 15 YRS 3 MONTHS
rather than 15 3
(i) DISPLAY LARGE AMOUNTS OF OUTPUT AS A TABLE,
HISTOGRAM OR GRAPH, AND GIVE TITLES.
For example:
TABLE 1: NET INCOME FOR B. JONES
FOR YEARS 1978-80
Box your tables if possible.
The user should not have to look up the program listing to see
what the numbers in the output mean.
au) DESIGN YOUR OUTPUT TO BE EASY TO READ
Plan it to be attractive to any user of your program and, of
course, yourself. Graphics is a powerful tool for this.
(iv) ALIGN, SPACE AND JUSTIFY THE OUTPUT
Plan your output with reference to the screen size and divisions.
For tables — align information central to the heading
align signs
right justify numbers
left justify characters.
(There are routines in the text for doing this). For example:
876-340 JIM SMITH
27-210 HUNG FO
453-003 SARAH JAY
1-025 DRACULA
NUMBERS
15.003
815.231
- 4.000
– 100.100
Fill in with zeros to get decimal placing correct.
(v) USE SPACE CAREFULLY
Sinclair computers use expensive printer paper! Print output
horizontally wherever possible. For example:
TABLE OF POWERS OF 2
2
4
8
16
32 etc
should be:
TABLE OF POWERS OF 2
2 £ 8 16 32
64 128 256 512 1024
(vi) DO МОТ OVERDO EXPLANATIONS
Be succinct!
(уп) MAKE YOUR ABBREVIATIONS CLEAR
x = 25
NDTC =25
NUMBER OF DAYS TO CHRISTMAS = 25
(vii) DISPLAY INPUT DATA AS AN OPTION
Allow checking of input data before processing.
Make your program check for incorrect or bad input data.
MODULAR DESIGN
We break problems down into sequences of steps to produce programs
in which different kinds of activities are separated out. These
distinctive program modules are our SUBROUTINES or SUB-
PROGRAMS. Each module has its own name and address, but in
BASIC we usually refer to program modules by address only, as with:
GOTO 100 and GOSUB 3300
where the address is the line number of the first statement in the
module.
We can address sub-programs or modules by name by assigning the
name and address of the module at the start of the program. For
example:
10 REM * ASSIGN MODULE NAMES *
20 LET INPUT DATA = 1000
30 LET PROCESSING = 2000
192
40 LET OUTPUT DATA = 3000
59 REM * END MODULE ASSIGN *
60 REM
70 REM * MAIN *
80 GOTO INPUT DATA
90 GOSUB PROCESSING
100 GOTO OUTPUT DATA
110 STOP
1000 REM * INPUT DATA MOD *
1500 GOTO 90
1600 REM * END INPUT *
2000 REM * PROCESSING SUBROUTINE *
2500 RETURN
2600 REM * END PROCESSING *
3000 REM * OUTPUT DATA MOD *
3500 GOTO 110
3600 REM * END OUTPUT MOD *
4000 REM * END PROG.*
There are good reasons for modular design and the use of subroutines
and sub-program modules. The logic of the program, i.e. its flow, is
easier to follow. The clarity of the structure of the main program is
improved whilst program design is proceeding by referring to the
number or name of the module initially, instead of starting to write out
the code of the module at that point. The module can be coded as a
separate entity.
Independent testing of modules is possible, but care must be taken
that all variables have been declared and have their correct values at
the start of the module. Debugging 1s simpler with this approach, since
the module is isolated. You can leave the coding of a module until a
later stage, but you must know what it will do when coded.
If a module has to be used several times in a program from different
places it need only be written once and called (into action) from these
points by reference to its line number or name.
193
Program modules can be designed to run sequentially:
START
MODULE 1
INPUT
MODULE 2
PROCESSING
MODULE 3
OUTPUT
STOP
This structure is convenient for simple programs. However, programs
can be structured in terms of subroutines and sub-programs being
called from a short and simple main program module.
START
MAIN
a MODULE
MODULE 2
MODULE 3
194
This structure is convenient for longer, more complicated, programs
with many modules and nestings.
Subroutines automatically return to the next line in the main program
through the RETURN statement. Other modules are called by GOTO
(line number) and return by GOTO (line number) instructions.
GOTO MUST BE USED WITH THOUGHT AND CARE AND
NOT EXCESSIVELY. Use a GOSUB unless a return to a different
point in the main module is needed or a multiple return is possible as a
result of a decision to be made within the module.
Nested modules can be treated as other modules and called from
within the subroutine or sub-program, by GOSUB and GOTO
instructions. Nested loops must be contained within the same module,
however.
CONTROL STRUCTURES IN SINCLAIR BASIC
(1) Each control structure is a program module.
(2) A formal pseudocode description of each structure is given of the
general form of the control structure.
(3) A flowchart description is given of the general form.
(4) The BASIC version is given of the general form.
(5) A simple example illustrates the BASIC form of the control
structure.
(6) Structures will be written in indented form in the pseudocode
version for clarity. You cannot indent in Sinclair BASIC
program listings. REM statements must be used to show the
start and stop lines for program modules.
(7) P is a processing operation. It can be a single instruction, a
statement or a group of statements.
(8) In the formal pseudocode each structure will commence with the
title module (abbreviated to mod), and end with the statement
endmodule (abbreviated to endmod).
(9 In BASIC cach structure will be bounded by
REM*STARTMOD* and REM*ENDMOD* statements.
(10) Flowcharts will be bounded by START and STOP symbols.
The structures summarised are:
A) Decision Structures
(1) Single decision
IF-T HEN structure
(п) Double decision
IF-T'HEN-else structure
(ш) Multiple decision
Case structure
195
B) Loop Structures
(i) repeat-forever loop structure
(ii) repeat-until structure
(iu) while-do structure
(iv) FOR-NEXT structure
The names of the structures are implemented as actual
programming language structures in other languages and some
forms of BASIC. The FOR-NEXT structure is a special form of
the while-do loop, given a specific implementation in BASIC.
A. DECISION STRUCTURES
() SINGLE DECISION: The IF-THEN structure
Meaning: IF (condition is true) THEN (do something)
Pseudocode Flowchart
mod
if (condition)
then P
endif
endmod
BASIC
10 REM*START MOD*
20 IF (COND) THEN P
30 REM* ENDMOD*
Example
Input a number and if it is positive, print it.
Pseudocode BASIC
mod 10 REM*START MOD*
input A 20 INPUT A
If A > Q 30 IF A>@ THEN PRINT A
then print A 40 REM*END MOD*
endif
endmod
196
(i) DOUBLE DECISION: The IF-THEN-else structure
Meaning: IF (condition is true) THEN (do something)
otherwise (if condition is false) do something else.
Pseudocode Flowchart
START
mod
if (cond)
then P1
else P2
endif
endmod
BASIC
10 REM*START MOD*
20 IF (COND) THEN GOTO 50
30 (FALSE TASK P2)
40 GO TO 60
50 (TRUE TASK P1)
60 REM*ENDMOD*
To perform the true task (P1 in the pseudocode) first, the BASIC
implementation of the structure would test the complement of
the condition, so that in the program below, for example, A>B
would be replaced by A<B, and lines 50 and 70 swapped. Note
the standard form of complement would be B< = A, but we have
defined the input numbers as unequal in this case.
197
Example
Input two unequal numbers and print the largest.
Pseudocode BASIC
mod 10 REM*STARTMOD*
input A,B 20 INPUT A
ifA>B 30 INPUT B
then print A 40 IF A» B THEN GOTO 70
else print B 50 PRINT B
endif 60 GOTO 80
endmod 70 PRINT A
80 REM*ENDMOD*
(ш) MULTIPLE DECISION STRUCTURE: The case structure
With this structure we want the program to select and perform
one of several alternative tasks.
The conditions in this case structure are sequential, not
nested and mutually exclusive.
Pseudocode Flowchart
mod
case
if (condition 1 is true)
then P1
if (condition 2 is true)
then P2
if (condition 3 is true)
then P3
end case
endmod
198
BASIC
10 REM*STARTMOD*
20 IF Cl THEN P1
30 IF C2 THEN P2
40 IF C3 THEN P3
320 REM*ENDMOD*
Example
Test whether a number input is positive, zero, or negative, and
print the result.
Pseudocode Flowchart
mod
input A
case PRINT
if A<0 NEGATIVE
then print “МЕСАТІУЕ”
If А = 0
then print “ZERO”
if А>0
then print “POSITIVE”
endcase
endmod
PRINT d
PRINT
POSITIVE
199
BASIC
14 REM*STARTMOD*
20 INPUT A
30 ЕА < 0 THEN PRINT “NEGATIVE”
40 IF A-0 THEN PRINT “ZERO”
5) IF A>@ THEN PRINT “POSITIVE”
60 REM*ENDMOD*
Alternatively, we can use conditional and unconditional GOTO
statements to implement this structure. This would be
appropriate if the processing section of a program after the
decision were several statements long, rather than the single
instruction available on the ZX81. Spectrum users can add more
instructions on the same line. They should be restrained in using
this facility.
10 REM*STARTMOD*
20 INPUT A
30 IF A< 0 THEN GOTO 60
40 IF A-0 THEN GOTO 80
50 IF A>@ THEN GOTO 100
60 PRINT “NEGATIVE”
70 GOTO 110
80 PRINT “ZERO”
90 GOTO 110
100 PRINT “РОБІТІУЕ”
110 REM*ENDMOD*
В. LOOP STRUCTURES
(1) The repeat — forever loop
Meaning: None. The only conceivable result is the program
halting with an arithmetic overflow report.
Pseudocode Flowchart BASIC
(такт) 10 REM*STARTMOD*
START
20 P
30 GOTO 20
mod
40 REM*ENDMOD*
repeat
P
forever
endmod
200
(i)
This structure is for demonstration only. Avoid using it in
programs! It can sometimes occur in error. Use BREAK if you
suspect your program has entered such a loop (because nothing
happens).
The repeat — until loop
Meaning: Repeat processing until a condition is true.
These structures loop until a specific termination condition is
met, for example until a counter reaches a certain value or until
a dummy or sentinel value 1s input. The important characteristic
of this loop structure is that the repeat test (or exit test) is at the
bottom of the loop, after the processing ‘body’. The program
lines making up the body of the loop (P) will be executed at least
once. The repeat condition can use any conditional operator or
its complement (reverse).
e.g. equals 4—0 not equal
- <>
Use of the complement often leads to a more elegant program.
Pseudocode Flowchart
mod
repeat
P
until (condition is true)
endmod
BASIC
10 REM*STARTMOD*
20 P
30 IF (COND) THEN GOTO 50
40 GOTO 20
50 REM*ENDMOD*
201
BASIC using complement
10 REM*STARTMOD*
20 P
30 IF (COMP COND) THEN GOTO 20
40 REM*ENDMOD*
Exit requires no specific instruction.
Example
Input and print strings until the sentinel value “LAST” is
input.
Pseudocode Flowchart
START
mod
repeat INPUT Ag
input A$
print A$
until A$ = LAST
endmod
PRINT Ag
Ag-LAST ?
BASIC
10 REM*STARTMOD*
20 INPUT A$
30 PRINT A$
40 IF A$=‘‘LAST’’ THEN GOTO 60
50 GOTO 20
60 REM*ENDMOD*
202
Complement Version
10 REM*STARTMOD*
20 INPUT A$
30 PRINT A$
40 IF A$<>‘‘LAST’’? THEN GOTO 20
50 REM *ENDMOD*
(ш) While — do structure
Meaning: While a condition holds (TRUE) keep repeating the
process until the condition is broken (FALSE).
The condition can be, for example, that a loop-counter
variable value is not equal to its final value (IF N<10 THEN..).
The process will then repeat until it is. The condition may also
be set so that a sentinel value has not occurred (IF N<>6
THEN). These conditions are set so that the true pathway is the
process task, and the false is the exit.
The While — do loop is characterised by having the repeat test
carried out prior to the body of the loop (i.e. at the top). No
processing will happen if the repeat test is false at the first
encounter, i.e. the body of the loop is never entered.
Pseudocode Flowchart
START
mod
while (condition is true)
do P
endwhile
endmod
BASIC
10 REM*STARTMOD*
20 IF (COND) THEN GOTO 40
30 GOTO 60
40 P
50 GOTO 20
60 REM*ENDMOD*
203
(iv)
Using the complement of the repeat condition gives a neater
program.
Complement Version
10 REM*STARTMOD*
20 IF (COND) THEN GOTO 50
P
40 GOTO 20
50 REM*ENDMOD*
Example
While the value of the square of consecutive integers is less than
100, print them on the screen.
Pseudocode BASIC (complement)
mod 10 REM*STARTMOD*
п = 1 20 LETN=1
while п*п< = 100 30 IF N*N>100 THEN
do print n*n GOTO 60
n=n+1 40 PRINT N*N
45 LET N=N+1
end while 50 GOTO 30
endmod 60 REM*ENDMOD*
FOR - NEXT Loops
FOR - NEXT loops are a special BASIC structure for repeating
a process a stated number of times. They are in fact While — do
loops and have the repeat test at the top of the loop.
Example
Print the values of the first ten integers.
Pseudocode BASIC
mod 10 REM*STARTMOD*
n= 1 20 FOR N=1 TO 10
While n < = 10 30 PRINT N
do print n 40 NEXT N
п=п+1 50 REM*ENDMOD*
епа while
епатоа
FOR - NEXT loops have their own special flowchart symbol,
because they are used so extensively in BASIC:
204
Ordinar Special
This is a condensed version. It groups together
the FOR — NEXT — STEP instruction elements,
which the standard form separates.
This illustrates both a
While do and a FOR-
NEXT structure.
O4: Program Development
Program Development involves the activities of DEBUGGING your
program of errors, TESTING to see if it behaves as specified and gives
the desired results, and DOCUMENTATION which tells users how to
run the program.
DEBUGGING
The Sinclair machines have good editing facilities and error messages.
Those on the Spectrum have brief statements of the error type, those on
the ZX81 have just a number or letter.
Although it is inefficient to correct errors one at a time (because there
is seldom only a single error since programming mistakes tend to
compound one another), error messages on the machine are produced
singly, since an error stops the computer from running. Thus we must
deal with the errors as they occur in the program sequence. You may
notice a number of errors on carefully looking through the listing. Any
you spot should be edited out at once.
GET TO KNOW YOUR COMPUTER ERROR CODES
This will happen automatically in time (as you make mistakes!), but it
is worthwhile studying the codes. They define the ways in which 'run-
time' errors occur, and an understanding of them will help you avoid
bugs.
205
EXIT
Keep a note of mistakes you have made and how you
corrected them. This will be valuable for future reference.
This should become an automatic part of your personal
documentation. Keep a copy of old program listings. Record the errors
you have made, the corrections you tried but which did not work, and
what you learned in developing the program.
Trace the impact of any error through the program.
SYNTAX ERRORS
These are caused by BASIC statements you key in which do not obey
the precise language rules (syntax rules) of Sinclair BASIC. The syntax
errors are detected by the LINE INTERPRETER which
automatically checks each line you key in when you press the
NEWLINE (ENTER) key.
If there is an error the interpreter will place the SYNTAX ERROR
cursor just before the first error it detects on the line. This may be at
the end of the line if the interpreter finds that something else should
have been placed there. To correct this type of error you must compare
the syntax you have written with the rules of BASIC.
Typing instructions incorrectly cannot occur on the Sinclair
computers as the BASIC 15 single key-stroke. In other BASICs you
must type P,R,I,N,T, for PRINT. Instructions in general are
automatically placed in the correct order along a line (i.e. the order of
line number - instruction — operand), since they are taken care of by
the mode controller which sets the cursors in the correct sequence.
Errors which can occur are:
1 Omission of line number
Line number too large (29999)
Line number negative
Line number non-integer
Omission of delimiters:
brackets (must be paired)
commas
semicolons
quotes
colons (on the Spectrum)
6 Typing in of improper variable names
7 Incorrect logical expressions
There can be more than one error per line. The S-cursor will re-appear
in the line when you try to enter it into memory. The line edit facility is
comprehensive and easy to use on the ZX81 and Spectrum.
You must correct your mistakes, and keep trying to ‘compile’ the
line into correct BASIC syntax (to be entered into memory). When
successful, the program line will appear at the top of the screen.
The syntax error check ensures no nonsense lines (from the
computer's point of view) are entered. It cannot help you in coding
correct sequences of program lines, or prevent logical errors.
сл ны оо ho
206
PROGRAM LOGIC ERRORS
These are the effect of bad logical design of the program. They can be
avoided if care is taken in the design and coding of the program. Ifa
program produces incorrect results then there is an error in the flow of
logic in the program. This may only occur with certain values of data.
If each program section or module has been tested independently
then the linking of the modules is incorrect. We can test program
sections as follows:
1) Insert a temporary breakpoint into the program, at the
appropriate point.
2) Print out values of intermediate results, to the screen or printer.
3) It is most important to print out the values of variables used in
making a decision and those used in loops, either counter loops
or FOR - NEXT loops.
4) Go back to the pseudocode or flowchart and modify the steps
which are in error. ‘Walk through’ the algorithm, using a
flowchart, to check the step sequence, and hand trace the
program with selected values of data and/or variables. Be
careful! Often changes in one part of the algorithm cause
changes in the others. It is no use solving one problem if it causes
another!
3) Change the documentation if necessary. Note down the changes
you have made, or lines you have deleted. Keep program
listings.
6) Re-test the complete program, using a variety of data.
Each testing statement in a complex program should be headed by a
remark statement.
1000 REM - DEBUG
— (Testing Statements)
- REM - END DEBUG
These temporary REM statements are later deleted by keying in their
line numbers, as are the testing statements. It is very easy to leave in
test instructions unless they are marked.
INSERTING BREAK POINTS
We can stop a program at any point and obtain the values of variables,
expressions, etc. to test calculations or check for errors. We do this by
207
Inserting a group of statements which will output the values we want
and then stop the program.
qM < ADD TEST OUTPUT OF VARIABLES
МШ < INSERT STOP STATEMENT
CONT will restart the program.
Individual modules or sections of program can be tested this way.
We do, of course, have to RUN the program from the required module
line number. Care should be taken when this is done that variables
needed in the module have been declared properly and that the values
of parameters passed to the module are as required. Remember that
you can INPUT the values of variables directly if necessary, using the
command mode, and using LET statements:
LET X(2) = 20, etc.
The value of any variable at the point the program crashed can also be
obtained by keying a statement without the line number, and again
using the computer in command mode:
PRINT A$
LPRINT X(3)
The commands RUN N (where N is the line number we wish to run
the program from) and GOTO N enable us to run the program starting
at any point. Using GOTO N does not negate the initialisation of
variables that occurs 2 the program has already run. For example, if
we input:
10 LET A=1
20 LET B = 2
39 PRINT A,B
and then key in GOTO 30, we get the error report ‘2/30’ (ZX81) or ‘2
Variable not found 30:1' (Spectrum) meaning an undefined variable
was found. If we RUN the program, we can then use GOTO 30, and
the program signals successful completion.
RUN-TIME ERRORS
These are a result of programmer carelessness and do not prevent the
interpreter from translating the program. They make the program
crash when you attempt to run it, that is they prevent the program
from running to completion. Common run-time errors are:
1) undeclared or unidentified variables
2) arithmetic overflow
3) lack of data for processing
208
4) failure to complete loop increment and subroutine section
statements
5) subscript out of range
6) memory full
7) screen display file full
8) integer out of range
As we have seen, run-time errors cause diagnostic system messages to
be printed. ‘These appear at the bottom of the screen and are called:
ERROR CODES
These errors can then be traced through the type of error given by the
code and the line number at which the program stopped.
ERROR CODES
Error codes or Report codes are presented on the screen when a
program stops for any reason, either as a result of successful
completion (no more program lines), an instruction or command
(STOP, BREAK), or a run-time error.
On the ZX81 the codes have the form E/N, where E is the code for
the type of error and N is the line number where the program was
stopped (STOP or BREAK), or where an error occurred. N is @ fora
direct command. This is an example of an error code on the ZX81
which is printed on the screen when an arithmetic overflow (number
larger than about 10% generated) occurs in line 60 of the program:
6/60
The Spectrum gives an extended error report code, with a brief
statement in the form:
E Statement N:S
where E is the report code, the statement is the reason for stopping
(with BREAK or STOP or program completion) or type of error. N is
the line number, but since the Spectrum can have multiple line
statements, the S number indicates which statement on the line the
report code refers to. We are not using multiple line statements in this
text, so S will always be 1, meaning the first (and only) statement on
the line, unless after the THEN in an IF... THEN statement, which 15
treated, like a colon, as a statement separator.
The Spectrum's version of the example given above (the ZX81’s
arithmetic overflow error code) is:
6 Number too big 60:1
Report codes are crucial aids to debugging programs. Without them
we would know only that we had an error, but not where it occurred or
what type of error it was. The error reports indicate both of these items
of information.
It is important to understand that the cause of an error may come
earlier in a program than the line where the program stopped. For
example, a code 2 error (variable not found), occurring in line 100 of a
program might be caused by a mis-spelt variable name in line 100 (not
209
the same as the variable you meant it to be — putting GUES when you
meant GUESS, for example). It could also be the result of not having
assigned the variable earlier in the program. If the error causing the
program to halt is not apparent from the line given in the error report,
the program flow must be traced backwards to find the prior cause. In
some cases this can be extremely difficult to track down - for example,
where a numeric value wrongly defined or generated by the program
causes another expression to cause an arithmetic overflow. Tracing
techniques must be used.
Lists of Error codes and their meanings for the ZX81 and Spectrum
are given in Appendix II.
TESTING AND VERIFICATION
Verify that your program works by testing it with Test Data
Testing comes after debugging a program. Its purpose is to ensure that
the program is logically correct, produces correct answers and meets
the specification of its purpose.
1 First test each module separately
Each procedure and subroutine should be treated as if it were a
separate program.
Test for (i) good data - the expected type and range of inputs.
(1) bad data — out-of-range and incorrect type inputs.
Try to ensure each procedure ‘fails softly’. For bad data (particularly
in any data entry module) following each input a check routine or
procedure should be used to give an error message if range is incorrect
or check type of input and correct syntax. This is best done with
strings, which are more flexibly handled. See Unit V which deals with
input checks at length.
2 Combine the modules and test the complete program
If there is a logical error (1.e. program does not produce the intended
results) insert additional test statements which will:
(i) Output intermediate results.
(11) Output values of variables at each stage.
(iii) Output results of expressions at each stage.
(iv) Output values of the loop counter at each pass.
(v) Output results of array manipulation after each
operation.
(vi) Output values of parameters before and after subroutines
entry and return.
3 Handle exceptions
(1) Test all data in the program.
(11) Screen all data.
(111) Process only good data.
(iv) Output bad data saying why it was bad.
210
4 Let your program stop elegantly
(1) When there is no data input or data available, the
program should tell you so.
(1) Sinclair BASIC programs are interactive. The user сап
control program continuation with:
910 PRINT “PROCESSING ENDED - MORE
DATA? ANSWER YES OR МО”
920 INPUT A$
930 IF A$ = “YES” THEN GOTO 100
940 PRINT “GOODBYE”
950 STOP
960 REM PROGRAM END
5 Rewrite the program until you are satisfied with it
Remember the program should be - structured
— easy to read
— easy to understand
— handle exceptions
— be as efficient as possible
— documented
and it must solve the problem as specified!
6 Put clarity before efficiency
To be good a program algorithm does not have to be clever, difficult to
understand or run super-fast. If you do not understand how the
algorithm works do not use it — rewrite and re-design or use another
method.
Programs will work correctly if the rules of the language are obeyed,
and the program will work to specification if the algorithm 1s properly
designed.
DOCUMENTATION
ANNOTATE AND DOCUMENT YOUR PROGRAM AND
CREATE A READABLE PROGRAM
1 Write an explanation for each program module or segment. At
the beginning of each segment provide suitable comments which
explain:
(1) the purpose of the algorithm
(2) the variables and their significance (the values they
store)
(3) the results expected.
2 Use comments only where necessary:
(1) don't comment each program line
(2) don't explain the obvious
(3) at the beginning of the program provide a block of
211
10
comments that explain the program at each module and
provide a comment which explains what the module does
in relation to the program.
Clear comments should appear separated from program code.
The clearest comments are framed. For example
19 REM * * * * * * * *
20 REM * SUBROUTINE TO *
30 REM * CALCULATE N TO 2 D.P. ы
40 КЕМ * i
50 REM * * * * * * * *
Lines of asterisks provide visible dividers between sections of
program.
Use comment in the program and in the output to the screen or
printer.
Use blank REM lines as separators in the program.
For large programs write a reference document:
(1) Describe the algorithm you used. If it is not original you
should include a note of its source, author, version, and
type of computer it was written on.
(ii) Explain how you wrote the program, the reasons for
writing it, the type of computer used and memory
required.
(ii) Make a note of areas that may need improving, or could
be modified for different purposes.
(iv) Which modules are general (menus, subroutines), and
which require specific kinds of input.
(v) Explain the scope and limitations of the program.
(vi) Include your name, and the date of production.
List the tests you made and data used. Reproduce some of the
results of the tests.
List performance tests (e.g. how long it takes the program to
run).
Give user instructions and reproduce the output of a run and
explain to the user how he uses the program.
Give the program characteristics. Explain any abnormal
behaviour of the program (e.g. response to bad input).
Write a brief USER GUIDE. This is mot for the computer
expert. It should explain:
— the purpose of the program
— the algorithm
— how to run the program
— what input is needed
— what results are printed
— how to use the menu (if included)
O5: THE COMPLETE PROGRAMMING METHOD
SUMMARY: THE STRUCTURED PROGRAMMING METHOD
1. | PRODUCE THE ALGORITHM
State the Problem fully
1.4
1.3
1.3
1.4
1.1.4
1,2,2
State the problem
Understand what is to be done
Research the Problem
1.2.1
1,24%
15,4
Research апа analyse the problem to see how the
computer can handle it
Identify all formulae and relations to be used.
Identify all data involved
Design the algorithm
Use top down structured methods:
152,1
1,5,2
1.5.3
1.3.4
1.2.9
1.3.6
Break the problem up into sub-problems ог modules.
Use a structure diagram or tree diagram to help in
breaking down the problem.
Start classifying modules or parts of modules as:
INPUT
PROCESSING
OUTPUT
Utilise the fundamental control structures in the modules
— Decision structures
— Transfer structures
— Loops
- Subroutines
- Nested structures
— Subprograms
Set up a DATA TABLE in which all data types are
classified as
Variables
Constants
Counters
Functions - if using a Spectrum and the DEF ЕМ
instructions
Define the algorithm further until coding it into a BASIC
language program is an easy and obvious exercise.
Describe the algorithm in Pseudocode and Flowchart form
1.4.1
1.1.2
1.4.3
Write out the final algorithm (now in modular form) in
small steps in an abbreviated English style called
Pseudocode.
Each module should be treated separately and !abelled.
Illustrate the logical flow of control in the algorithm by
constructing a flowchart.
Test the algorithm, if necessary using a hand trace or
walk through.
213
2.
2.1 Code the Algorithm in SINCLAIR BASIC
2.1.1 Code on a direct basis from the pseudocode or flowchart
description in line numbered BASIC statements, module
by module.
2.1.2 Implement the fundamental control structures, used in
their SINCLAIR BASIC versions.
2.2 Debug and Test the Program
2.2.1 Debug the Program. Check the program variables against
your algorithm test. Correct syntax, run time, and logical
errors.
2.2.2 Test the program for further logical errors. Run the
program with sample data.
2.3 Document the Program
For a full documentation, you should:
2.3.1 Produce a programmers’ guide consisting of:
pseudocode
flowchart
variable table or data table
program listing
test results or sample printout.
2.3.2 Detail the steps that producing the program involved.
2.3.4 Write a user guide.
214
PROGRAMMING: SUMMARY OF METHOD IN FLOWCHART FORM
This provides a diagrammatic version of the summary of structured
START
FIND OUT WHAT YOU
HAVE TO DO.
programming:
STATE THE PROBLEM
DRAW A STRUCTURE
DIAGRAM OF HOW YOU
ARE GOING TO SOLVE
THE PROBLEM.
(THE ALGORITHM )
WRITE A
DESCRIPTION OF
THE ALGORITHM.
PRODUCE A
FLOWCHART
CONDUCT A
WALKTHROUGH
ERRORS
?
No
В)
215
CODE INTO BASIC
FIND ERRORS AND
CORRECT
RUN A TEST
ERRORS
?
No
TEST FOR RUN TIME
& LOGIC ERRORS
DOES IT
DO WHAT YOU
WANT IT TO DO?
No
Yes
IS THERE
MORE YOU NEED TO
KNOW ABOUT THE
PROBLEM?
TEST FOR EXCEPTIONS
& GET SOMEONE ELSE TO
TRY IT OUT.
THIS PROBLEM NEEDS
A RE-THINK. PUT
EVERYTHING ELSE ASIDE,
AND DON'T RUSH
ERRORS
2
No
WRITE DOCUMENTATIO
OF HOW IT WORKS,
FLOWCHARTS
AND DOCUMENTATION
OF HOW TO RUN THE
PROGRAM.
END
AN EXAMPLE OF STRUCTURED DESIGN
5
2.
2.
4.
Problem Statement
Write a program that computes and prints the Average or Mean
(M) and Standard Deviation (S) of a collection of N data items.
To compute SŠ use the formula:
Standard Deviation = Sum of Š A of Items) _ (Mean)
Find out what we have to do (research the problem)
We are given most of the information in the question but we are
missing some. It does not tell us how to compute the Mean or
Average. This is given by the formula:
(Sum of all numbers)
Mean = N
We now have all the information, we need to start designing the
algorithm.
What is involved in this problem
The outline procedure we can now define:
a) We have to INPUT the numbers, and
b) Perform two calculations on these numbers. First we calculate
the Mean and then use the Mean value to calculate the
Standard Deviation, then
c) Output the results.
Design the algorithm
This gives the detailed procedure for the steps needed to solve the
problem:
a) INPUT
The numbers are going to be input into an array because they
will be needed twice in the calculation module.
b) 1. Calculate: the Mean —
Add all the numbers in the array and divide by N.
2. Calculate: the Standard Deviation -
Total the squares of all the numbers in the array.
Use the formula to calculate S.
c) Output: the Results —
The results will be printed on new lines with the words
MEAN = and STANDARD DEVIATION =
followed by their values.
217
5. The Tree Diagrams
1. Compute and print
Standard Deviation
and mean
Results
Each of modules 1.1, 1.2 and 1.3 will be subroutines. These will be
called in the appropriate sequence by the main program module.
INPUT
1.14.2 1.143
ASK HOW MANY INPUT N NUMBERS
NUMBERS AND
INPUT N
1.1.1.1
DIMENSION 1.1.3.2
ARRAY ; FOR I-1 TO N,
Y(50) INPUT Y(I)
FIND MEAN AND STANDARD
DEVIATION
1.2.4 1.25.34
^
c
CALCULATE STANDARD
FIND MEAN
DEVIATION
1, 2.1. 2
SUM ALL DIVIDE SUM BY NUMBER
ELEMENTS OF ELEMENTS
FOR I = 1 TO N LET MEAN =
SUM DIVIDED BY N
LET SUM = SUM + Ү(І)
218
1.2.2.
CALCULATE STANDARD
DEVIATION
1.2.2.1; ls£s2. 2.
CALCULATE SUM OF USE FORMULA TO
THE SQUARES CALCULATE STANDARD
DEVIATION
ГЕ ТУРУР PI UM PX
INITIALISE FOR EACH
VARIABLE ELEMENT GET
SQUARE, ADD
TO TOTAL
LET SUM
HN FOR I=] SQR-SUM
TO N SQR«Y(I)
**?
( f ON
SPECTRUM)
Led
OUTPUT
RESULTS
lesel
PRINT "MEAN = ";
MEAN
1.3.2
PRINT "STANDARD
DEVIATION = '5S
219
6.
The Flowcharts
The Main Program
module flowchart:
GOSUB
INPUT
SUBROUTINE
GOSUB
PROCESS
SUBROUTINE
GOSUB
OUTPUT
SUBROUTINE
220
The Input Subroutine
flowchart:
ENTER
CREATE
ARRAY
Y(50)
PRINT
"HOW MANY
NUMBERS?"
INPUT
N
INPUT
NUMBER Y(I)
RETURN
The Processing
Subroutine flowchart:
ENTER
LET SUM
= SUM +
LET SUMSQR
LET SUMSQR
ET S=SQR
(SUMSQR/N)
(
- (MEAN**2) )
SPECTRUM FORMULA
USES 7, NOT **,
RETURN
222
The Output
Subroutine flowchart:
ENTER
PRINT
MEAN
PRINT
"STANDARD
DEVIATION="
PRINT
RETURN
223
7. The Program
ед
The Мат Program Моаше
REM "SDEVIATIDN"
FEM 339 9 3 3 9 ЗЕ ЗЕ ЗЕ C 3 9€ 93639963
жҰМАТМ FROGRAM MOLD жж
REM **INFLUT DATA жж
GOSUE 100
REM **CALCILATE*
GOSUE zoo
REM ##FRINT RESLULTS3*
BOSE 400
= TOF
КЕМ **ENI! MAIN жж
5 ы ЭЕ ЗЕ ЗЕ ЗЕ ЭЕ
7.2 The Input Subroutine Module
95
100
110
120
130
140
SQ
160
170
120
190
КЕМ жж А ЗЕ ЭЕ ЭЕ ЭЕ ЖЕ Ж
X*INFUT SUBROUTINE жж
DIM Y(S05
FRINT “HOW MANY NLMEEFRZ?'":
INFLIT N
FRINT N
FOR Ізі ТОМ
INPUT YLI)
PRINT ҮСІЗ;" "3
NEXT I
RETURN
REM *#*#END INFUT SUE жж
аз
7.3 The Calculation Module
200
210
220
220
240
220
260
270
290
290)
300
210
—O
FEM 339 3 € € 3C 9€ 9€ 9€ 9€ 9€ 3€ 303030 3E 3E HE
XxCOLCULATION SUE жж
SUM=0
FOR Ісі ТОМ
LET SUM=SUM+Y C1)
NEXT I
LET MEAN=SUIM/N
LET СИМЕПК-О0
ЕПЕ Ісі TON
LET ФШИМЕОПЕ-СИМФОЕ-һ
(Y (I) X 2
NEXT I
LET $= Sik
(MEAN жж
ЕЕТМЕМ
LET
[ ^ Spectrum]
2⁄2
ССӘПМЕШЕ/М2-
29)
FEM **END CALC ‘Sue мен
JC 3 3C 3C 30 3636 Ж 9C EE EE
7.4 The Output Module
400 REM 33939 9c X X 3€ 9€ 3C € 9€ 9€ 3€ EHH
#*H0UTFUT SUBROUTINE жж
410 PRINT
420
FRINT "МЕАМ-“?МЕАМ
430 PRINT
224
440 PRINT “STANDARD DEVIATION
450 RETURN
460 REM **END OUTPUT SUB жж
333€ CICERO JEDE E EXER ЭН
8. Documentation
1) This program will compute and print the Mean and Standard
Deviation of a collection of data items (numbers).
2) It allows for a maximum of 50 items to be entered. You can
increase the size of array Y if you wish to deal with more data.
3) The numbers can be of any size, positive or negative, to the
limit of the computer's handling capacity. This is large — you
will not exceed it.
4) To run the program key in RUN, and enter numbers one at a
time, presing NEWLINE (ENTER) after each one has been
keyed in.
Sample run to find Mean and Standard Deviation of 30, 31,
22, 5, бу 7, 30, 12. 22, 3:
HOW MANY NUMBERS ? 10
20 31 325 6 7 10113 27 5
MEAN = 16.4
STANDARD DEVIATION = 11.45603
Exercise
The example program to compute and print the standard deviation of a
set of data items does not include a pseudocode description of the
algorithm, and the documentation process is incomplete in other ways
too.
i
2,
Complete the programming procedure by doing the following:
Write out a pseudocode description of the algorithm.
Perform a pre-coding walk through, checking the values of
the variables, counters and expressions for each subroutine
module.
Key in the program and debug it.
Insert breakpoints in each subroutine and perform a program
trace. Insert PRINT statements to print out values of
variables, counters and expressions.
Obtain a program listing from the printer and run the
program for a sample set of data. Keep a copy of the printer
output.
Document the program fully in your notebook.
225
SECTION P: THE CHARACTER SET AND CODES
Pi: The ZX81 Character Set and Codes
CODE/CHR$ CODE/CHR$
Ü - K] 49 L
1 F] 50 M
E ГЛ 51 N
3 = 52 O
4 kl 53 P
5 D 55 r0
от 55 R
7 P 56 S
o B 57 ў
9 ШЫ 58 U
uw m 59 V
11 n 60 W
12 £ 61 x
13 $ 62 Y
14 : 63 2
15 ? 64 RND
16 ( 65 INKEY£
17 66 PI
18 67
19 68
20 - 69
21 4 70
22 = 71
23 * 79
24 / 73
95 74 МОТ
26 75 USED
27 | 76
28 0 77
29 1 78
30 2 79
31 2 80
32 + 81
33 5 82
34 6 83
35 7 84
36 8 85
37 9 86
38 A 87
39 B 88
40) С 89
41 D 90
42 E 91
43 F 99
44 * 93
45 H 94
46 I 95
47 J 96
48 K 97
226
CODE/CHR$
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
NOT
USED
+ Å <>
GRAPHICS
EDIT
NEW LINE (ENTE
RUBOUT (DELET
K/L Mode
FUNCTION
NOT
USED
NUMBER
CURSOR
БЕЙБЫТ” лы | ТЫШ
inverse ``
Inverse £
Inverse $
Inverse :
Inverse ?
Inverse (
inverse )
inverse >
CODE/CHR$
147 inverse <
148 inverse =
149 inverse +
150 inverse —
151 inverse *
152 inverse /
153 inverse ;
154 inverse ,
155 inverse .
156 inverse 0
157 inverse 1
158 inverse 2
159 inverse 3
160 inverse 4
161 inverse 5
162 inverse 6
163 inverse 7
164 inverse 8
165 inverse 9
166 inverse À
167 inverse B
168 inverse C
169 inverse D
170 inverse E
171 inverse F
172 inverse G
173 inverse H
174 inverse I
175 inverse J
176 inverse K
177 inverse L
178 inverse M
179 inverse N
180 inverse O
181 inverse P
182 inverse О
183 inverse R
184 inverse S
185 inverse T
186 inverse U
187 inverse V
188 inverse W
189 inverse X
190 inverse Y
191 inverse Z
192 тар
193 АТ
194 ТАВ
195 (МОТ USED)
196 CODE
197 VAL
198 LEN
199 SIN
200 COS
201 TAN
202
ASN
CODE/CHR$
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
227
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
ACS
ATN
LN
EXP
INT
SOR
SGN
ABS
PEEK
USR
STR$
CHR$
NOT
жж
OR
AND
< =
> =
<>
THEN
TO
STEP
LPRINT
LLIST
STOP
SLOW
FAST
NEW
SCROLL
CONT
DIM
REM
FOR
GOTO
GOSUB
INPUT
LOAD
LIST
LET
PAUSE
NEXT
PI
PRINT
PLOT
RUN
SAVE
RAND
IF
CLS
UNPLOT
CLEAR
RETURN
COPY
Of the non-printing characters, those that are used, but print a question
mark, are the following:
116-121 inclusive
126-127 Inclusive
(NOTE: 5 1s the question mark.)
192 is the Quote image character, which prints a single quote. The
character set is coded with the numbers 0 to 255. This, you may recall,
is the number of values held in a single byte. The characters can thus
be accessed with a single byte identification code. This is also the
reason why some codes are listed, but have no character associated
with them. The same is true of the Spectrum character set, which
follows.
P2: Spectrum Character Set and Codes
Code Character Code Character Code Character
0 35 ж 70 Е
1 36 $ 71 G
2 37 % 72 H
3 not used 38 & 73 I
4 39 | 74 Ј
5 40 ( 75 K
6 PRINT comma 41 ) 76 ІР
7 EDIT 42 it M
8 cursor left 43 + 78 N
9 cursor right +} ; 79 О
10 cursor down 45 — (minus sign) 80 P
11 cursor up 46 ; 81 о
19 DELETE 47 / 82 R
13 ENTER 48 0 83 5
14 number 49 1 84 d
15 not used 50 2 85 U
16 INK control 51 3 86 V
17 PAPER control 52 4 87 W
18 FLASH control 53 5 88 x
19 BRIGHT control 54 6 89 Y
20 INVERSE control 55 7 90 Ж
21 OVER control 56 8 91 [
22 AT control 57 9 92 /
23 TAB control 58 : 93 ]
24 59 š 94 f
25 60 < 95 aa
26 61 = 96 £
27 not used 62 > 97 a
28 63 ? 98 b
29 64 @ 99 C
30 65 A 100 d
31 66 B 101 e
52 space 67 C 102 f
33 ! 68 D 103 g
34 69 Е 104 h
228
Code Character Code Character
105 i 159 (p) 213 MERGE
106 j 160 (q) 214 VERIFY
107 k 161 (r) 215 BEEP
108 l 162 (s) 216 CIRCLE
109 m 163 (t) 217 INK
110 n 164 (u) 218 PAPER
111 о 165 RND 219 FLASH
112 p 166 INKEY$ 220 BRIGHT
113 q 167 PI 221 INVERSE
114 r 168 FN 222 OVER
115 S 169 POINT 223 OUT
116 t 170 SCREENS 994 LPRINT
117 u 171 ATTR 295 LLIST
118 у 172 АТ 226 STOP
119 w 173 TAB 227 READ
120 x 174 VAL$ 228 DATA
121 y 175 CODE 229 RESTORE
122 2 176 VAL 230 NEW
123 { 177 LEN 231 BORDER
124 | 178 SIN 232 CONTINUE
125 } 179 COS 233 DIM
126 ~ 180 TAN 234 REM
127 © 181 ASN 235 FOR
128 т 182 ACS 236 GO TO
129 а 183 ATN 237 GO SUB
130 P| 184 LN 238 INPUT
131 = 185 EXP 239 LOAD
132 n 186 INT 240 LIST
133 e 187 SOR 241 LET
134 a, 188 SGN 242 PAUSE
155 ШТ 189 ABS 243 NEXT
136 m 190 PEEK 244 POKE
137 =" 191 IN 245 PRINT
138 B 192 USR 246 PLOT
139 p 193 STR$ 247 RUN
140 == 194 CHR$ 248 SAVE
141 all 195 NOT 249 RANDOMIZE
142 L. 196 BIN 250 IF
143 Kj 197 OR 251 CLS
144 (a) 198 AND 252 DRAW
145 (b) 199 = 253 CLEAR
146 (c) 200 = 254 RETURN
147 (d) 201 <> 255 COPY
148 (e) 202 LINE
149 (0) 203 THEN
150 (g) 204 ТО
151 (Һ) 205 STEP
152 (i) 206 DEF FN
153 (j) 207 CAT
154 (k) { user 208 FORMAT
155 (1) ( graphics 209 MOVE
156 (m) 210 ERASE
157 (n) 211 OPEN #
158 (o) 212 OPEN #
229
There is an important point to be noted with regard to the Spectrum
character set, which does not apply to the ZX81. Among the Spectrum
character set, codes 16 to 23 are control characters which are
used to specify certain attributes of the character cell for printing
purposes. These require arguments within a certain range (0 to 9 for
colours, or 0 and 1 for on or off, etc.). Codes 6 to 14, 22 and 23 are also
control characters for printing and editing. The problem with using
CHR$ with these control characters is that they can be used in
programs, and are then called by inserting, e.g. CHR$ 20, followed by
the argument. This means that a simple call to PRINT one of these
CHRS will cause the computer to think it is being given an instruction,
and the syntax demands an argument. If this is not forthcoming after
the CHR$, or the argument is in the wrong range, an error message
results when the Spectrum cannot do what it thinks it is being asked to
do.
Some of these control characters, however, for colour (dealt with in
Section W), and also for print control can be usefully placed in
programs. If we take CODE 8, which is a cursor control character, we can
write a program like this:
10 PRINT ‘‘SIN”’;
20 PAUSE 50
30 PRINT CHR$ 8;CHR$ 8; “АСКЕПр”
The CHRS 8 instructions in line 30 backspace the cursor twice, re-
setting the PRINT position, so that “АСКЕР” overprints “ТМ”, The
upshot of this is that we cannot print out the character set of the
Spectrum completely, but must start from CODE 24, after the control
characters. This is no great loss, since they print (or would print, if you
could get them to!) either a space or a question mark. Remember these
control characters, though, as they can sometimes be useful in a
program, although mostly it is far more convenient to use the BASIC
instructions. For example, we can use CHR$ 23 instead of TAB:
10 PRINT CHR$ 23;10; “ТАВ CONTROL"
This is not an advantage over using TAB! However it does show how
these characters are used by the computer- it inserts them into
program listings where the control function (e.g. T'AB), has been used.
TAB itself does not have a control function, and needs CHR$ 23 placed
after it to work.
P3: Characters
The ZX81 and Spectrum have a character alphabet consisting
of 256 items which include numeric characters, alphabetic
characters, keywords, instructions, commands, operators,
graphics and inverse graphics symbols and other symbols. As
230
seen in the tables in the previous Units, of these 256 items
some are not used at all, and some are non-printing (i.e.
control characters).
In Appendix III the ZX81 character codes are laid out by
character type and their position on the keyboard. Spectrum
codes are referenced alphabetically in Unit W1.
The CODE (occupying a single byte) identifies each
character uniquely for input/output purposes – i.e. input
from the keyboard and output to the screen or printer.
The ZX81 has a non-standard character set unique to the machine.
The Spectrum has a character set in which the characters used have the
codes of the ASCII character set (an internationally agreed standard)
for the most part. Non-standard ASCII characters are the symbols for
£ and ©, and the graphics characters.
Р4: CHR$ and Code
The purpose of the instructions CODE and CHR is to convert from
the code to the character and vice versa. The ZX81 and Spectrum have
different character sets and codes, but the instructions work in the
same way.
CODE
CODE is a function that takes a character or string and gives
as a result the numeric code that the character (a single
letter string, or first character in a string) cor-
responds to. For example:
CODE S gives 56 on the ZX81, 83 on the Spectrum
CODE “ABCD” gives CODE А, 38 on the ZX81, 65 on the
Spectrum
CODE X$ gives the code of the first (or only) character
in X$
CODE D$(3) gives the code of the third character in D$.
CHR$
CHR$ (N), where N is a numeric expression with a value
0 < = N < = 255, is a function that gives as a result the single
character whose code is N. CHR$ does the opposite of CODE.
For example:
CHRS (A + B + C)
CHRS$ (X/Z)
CHR$ (INT(RND * 255))
CHR$ 36 gives 8 on the ZX81, $ on the Spectrum
231
To see the inverse relationship of CHR$ and CODE, key in the
following as direct commands:
PRINT CHR$ 50 will print M on the ZX81, 2 on the
Spectrum
PRIN T CODE 52" ° will print 30 on the ZX81, 50 on the
Spectrum
PRINT CODE CHR$ 50 will print 50
PRINT CODE “A” will print 38 on the ZX81, 65 on the
Spectrum
PRINT CHR$ 38 will print A on the ZX81, & on the
Spectrum
PRINT CHR$ CODE “А” will print A
The next program will print out all the characters used on the ZX81.
10 FOR Е=0 TO 255
20 SCROLL
20 PRINT Е, CHR F
40 NEXT F
For the Spectrum, as noted above, we must miss out some CHR$ and
line 20. Line 10 must read FOR F = 24 TO 255. Key it in and run it.
Add:
3:9 LPRINT F; TAE à: CHF F
to get a printer listing. A better program (since it uses less printer
paper!) but one with an expression you won't understand until we
cover logic, is this one:
10 REM ##CHARACTER ЕТЖ
20 LFRINT "CODE/CHE$": TAB 10;
"CODE/ICHR$":; TAB zZO:"CODE/CHRE$"
30 FOR Е=0 To 85
40 LFRINT F? ТАЕ 4; CHES F;
ТАБ 10;F+sé; TAE 14; CHES$
CF+ie); ТАЕ 20% (F+172 AND
F+172<25693; TAE 24; CHES
(F+17Z AND Е+172<256)
ou NEXT F
Use these lines for the Spectrum version:
20 FOR Ғ-24 To 77
40 LPEINT F; TAE 4; CHES F;
TAE 10:F*77: ТАР 14: CHES
(Е%773; TAB 20:Е+154; TAE 24:
CHES (F+154)
Exercises
1 Key in and run the following programs. You may find some
surprising results, due to the control characters, on the
232
Spectrum. No harm will be done.
(a) 10 FOR F = 0 TO 255 (Spectrum: FOR Е = 24 ТО 255)
20 PRINT CHRS F;
30 NEXT F
Notice that the word characters print with the spaces that
your computer automatically inserts in program lines.
(b 10 RAND
20 PRINT CHR$ INT (128* RND + 128)
30 GOTO 20
(c) 10 INPUT A$
20 PRINT A$, CODE A$
30 GOTO 10
(d) 10 PRINT “INPUT STRING OF 6 CHARACTERS"
20 INPUT A$
30 FOR F =1 TO 6
40 PRINT A$(F), CODE АЖЕ)
50 NEXT F
(e) 10 RAND
20IF INT (RND*2)=1 THEN PRINT CHR$ INT
(RND*128)
30 IF INT (RND*2)-0 THEN PRINT CHR$
(INT(RND*128) + 128)
40 GOTO 20
(f 10 RAND
20 LET A$ = CHR$ INT (RND* 255)
30 SCROLL
40 PRINT CODE A$, A$
50 GOTO 20
In this last program, Spectrum owners can omit line 30 and
simply respond to the Scroll? prompt by pressing ENTER.
Write a program that given a number (code), will check that
0 < = code < = 255, and will print out the character. On the
Spectrum, the program should print “CONTROL
CHARACTER” if the CODE is between 6 and 23.
Write a program that when given an alphabetic character as an
input will print out the next in the alphabet. If the character
input was ‘Z’ then ‘A’ should be printed.
SECTION О: GRAPHICS
Q1: More Printing
Since we dealt with the PRINT instructions, you have been introduced
to other statements that can be used with the PRINT statements for
format and manipulation.
Loops are of use in printing. For instance we can set up an empty
string with 32 spaces and use it to clear different areas:
20 LET A$ = ‘‘(32 врасев)”
ЖІТІ
ӘЛГІ
100 FOR Х-11 ТО 21
110 PRINT АТ X, 0; A$
120 NEXT X
will clear the bottom half of the screen, and we could use it repeatedly,
as a subroutine, if we wished. We then avoid using CLS, which would
mean re-printing anything that we wanted to keep on the screen.
Except for numbers, anything we wish to print must be in the form
of a string, either between quotes, a string variable, part of a string
array, or a CHR$(X) instruction.
Obviously any operations or functions used with strings may be
useful, and in the same way as:
10 PRINT (1 + 3)
prints 4, we can use:
20 PRINT A$ (X TO Y)
to extract the desired characters of A$.
Enter and run this program
10 LET A$-"ABRACADAEEA"
20 LET L= LEN ñ$
30 FOR X=1 TO 6
40 PRINT TAE 10+X;ASCX ТО
Lela}?
20 NEXT X
Remember that numbers can always be treated as strings, and vice
versa, using VAL and STR$. This is often useful for formatting
numbers. For example, with a number X, this program:
234
10 LET A$="0000"
20 LET BS= STRS X
ЗО FOR F-1 Tü 4
40 IF LEN B$4F THEN GOTO 70
20 LET A$(CFD-E$CF?
&O NEXT F
70 PRINT A$
will print (һе first four digits of any number, ог follow (һе number with
zeros if less than 4 digits. Change the zeros to spaces, and you have a
number string that will overprint any other string however many digits
are in the original.
Code the program in with A$ = (4 spaces)’ and try it. As it is, you
wil have to enter X as a direct command (LET Х= 123, then
NEWLINE/ENTER) and then use GOTO 10, since RUN would
clear the variables (in this case, the value of X you have just entered).
This principle can be expanded. Here is an example of a subroutine
used to justify numbers and print them in the position required for the
decimal places to be in the same column:
10 REM "FORMAT"
20 REM *FORMAT SUBROUTINE For
*NUMEERS ж
30 REM #COLUMN NUMBER ЕСЕ +
*#DECTMAL РАСЕ +
40 LET t=12
S0 REM *INITIALISE GOSUB*
ео LET ҒОЕМАТ-УООО
70 REM *NUMBER*
во INPUT М1
7O REM #*#INITIALIZE NUMEER*
100 LET N=N1
110 GOSUE FORMAT
200 REM *MORE NUMBERS +
210 FOR ісі TQ 4
220 INFUT N
220 GOSWE FORMAT
240 NEXT L
2020 GOTO 999
2770 REM HHH EEE
Xe SIE ROUT INE жж
7000 LET N$- STF$ М
9010 LET Р=0
7020 FOR F=1 TO LEN МФ
ЭО20 IF МФ(ҒО-"." THEN LET F-F
7040 NEXT F
2050 IF F=1 THEN LET N$="O"+N%
7060 LET F=F+(P=1)
7070 IF F=0 THEN LET F= LEN N$+1
7020 FRINT TAE (C-F+1)7N%
vOTO FETLIFN
7100 REM ЖЖЕМПЕПЕ ЕЕ € 3€ 9€ 3€ 9€ 3€ 3€
92999. SIUF
Lines 10 to 240 are a main program to initialise and provide numbers
for the subroutine. Notice it adds a 0 if the number is a decimal. Line
235
9030 sets a marker for a decimal point in the first letter of the number
string, and adding а 0 is done in line 9050. 9060 uses the logical value of
(Р = 1) to add 1 if a zero was added, i.e. if P = 1 is true. This will be
explained in the Section on Logic, but the line is equivalent to IF P = 1
THEN LET P = 2. Check this by trying both versions of the line. Line
9070 adjusts the length of the string if there is no decimal place found
(i.e. if the number was an integer). 9080 prints the number in the
correct column.
The next program shows a simple way of tabulating results, using a
loop:
10 PRINT “МО.”;ТАВ 4;‘SSOQUARE”’; TAB 12;
"CUBE -TAB 20“ RECIP”
20 FOR N=1 TO 10
30 PRINT N;TAB 4;N*N;TAB 12;N**3; ( 1 on Spectrum)
TAB 20;1/N
40 NEXT N
NO. SQUARE CUBE КЕСІР
1 1 1 1
2 4 8 0.5
3 9 27 0.33333333
4 16 64 0.25
3 25 125 0.2
6 36 216 0.16666667
4 49 343 0.14285714
8 64 512 0.125
9 81 {29 0.11111111
10 100 1000 0.1
It is important to remember that numbers are output with 8 figures and
allow the appropriate space. An alternative is to decide how many
figures you want and use the INT function.
For example, we can replace 1/N in line 30 by INT(1E4*(1/N) +
.5)/1E4 , and get a printout like this:
NO. SQUARE CUBE КЕСІР
1 1 1 1
2 4 8 0.5
3 9 87 0.3333
4 16 64 0.25
5 25 125 0.2
6 36 216 0.1667
7 49 343 0.1429
8 64 212 0.125
9 81 729 0.1111
10 100 1000 0.1
236
Using the E notation allows easy definition of the number of decimal
places, without the possibility of missing a zero as, for example, if we
used INT(10000*(1/N) + .5)/10000, since using 1E4 gives four d.p.,
1E3 three d.p., etc. In using this, be careful with the bracket placing,
as INT(1E4*(1/N)) + .5/1E4 will not round! Try both the correct and
Incorrect versions in the program.
You should note that:
With PRINT TAB C; or PRINT AT L,C instructions L апа С
can be dependent or calculated variables. For example:
PRINT TAB (X*2)/3;
PRINT AT 10, 20/X;
Try these:
10 FOR X=1 TO 5
20 PRINT AT X, X. * 2:X
30 NEXT X
10 FOR X -1 TO 5
20 PRINT TAB X * 2X
30 NEXT X
An automatic INT function operates with PRINT AT
instructions.
For PRINT AT (L), (C); if (L) and (C) > nand < n +1,
(1) and (C) = n
For example:
PRINT АТ 3/2, 10.5;°°...”’
equals PRINT АТ 1,10;°°...”’
Try this:
10 FOR X - 1 TO 10
20 PRINT AT X, X/2; X
30 NEXT X
The AT function rounds down, exactly as if we had used PRINT AT
X, INT (X/2); X as line 20.
PRINT TAB(N), where N is non-integer, rounds to the nearest
integer.
TAB N, where N is between X and X + 1, gives TAB X if
N< X+ .5 and TAB X+ 1 if N2- X + .5. For example
TAB (1.3) =TAB 1
TAB (1.5) = TAB 2
237
To see the difference, RUN both these programs, use COPY to get a
printout, and compare the results.
10 FOR X=0 TO 10
20 PRINT TAB X/2;:X
30 NEXT X
10 FOR Х=0 TO 10
20 PRINT ТАЕ INT (X/2);X
30 NEXT X
You must also watch for arithmetic mistakes in calculating the PRINT
position. For instance:
10 FOR X=0 TO 10
ZO PRINT TAB 20/Х%Х
20 NEXT X
is not going to get past line 20 the first time round! Why?
This next example illustrates the use of PRINT AT to give changing
display.
A die is rolled and we wish to display its value for each of a series of
throws. In addition we require cumulative values after each throw.
Thus each time line 90 is reached it overprints line 70 and vice versa.
Similarly line 120 overprints itself after each throw.
> REM "DICEROLL"
10 PRINT "NUMBER OF THROWS?"
го INPUT X
20 DIM NCE)
sm CLS
40 PRINT АТ 2.27 "CUMULATIVE VA
LUES"
o0 FRINT АТ 10,47 "1929639639696
43x d T a жан
60 FOR M=1 TO X
é5 PRINT AT 1:3; "THROW"? ТАЕ 1
4; "VALUE"
70 PRINT АТ 32107 "ж". "ж"
SO LET ñ= INT (ёж RND +1)
20 PRINT АТ 3:103MsA
100 LET NCA =NCAI+1
110 FOR Есі TO é
120 PRINT AT 12:4*E;N(B)
120 NEXT Б
140 МЕХТ М
(М.В. Choose a relatively small value for X (say 24) or the program
will take a long time to run.)
238
Exercises
1 Modify the FORMAT subroutine to round the number to 3
decimal places before determining the print position.
2 Modify your result for the exercise above to print zeros for any
decimal place not filled.
3 Write a program that displays the result of throwing three dice,
displaying the result for each die, and the total value for each
throw. Overprint the last result with each new one, and store the
total values resulting. After the specified number of throws,
derive the average value for a throw.
Q2: More Plotting
Although the definition of the graphics on the ZX81 is low, the
computer has the capacity to draw useful graphs, and most graphics
processes can be illustrated. This is a program that draws a line
between two specified points:
10 INPUT Xl
20 INPUT Yl
30 INPUT X2
40 INPUT Y2
50 LET X=X(2) -X(1)
60 LET Y=Y (2) -Y(1)
65 LET A=(X AND ABS X>=ABS Y) +
(Y AND ABS X<ABS Y)
79 LET DX=0
80 LET DY=0
90 FOR F=1 TO ABS A
100 PLOT DX+X(1), DY+Y(1)
110 LET DX =DS+X/ABS A
120 LET DY=DY+Y/ABS A
130 NEXT F
The logic in line 65 checks which is the greater of the distances to be
covered between the points, and makes A equal to that, since the
smaller value will be in a false statement, and will be evaluated as 0.
You will have to wait until we deal fully with logical operations for the
explanation of the reason this works. The program library has an
expanded version of this program (“LINE”).
Spectrum owners should relish the fact that their machine’s ability to
accept a simple DRAW X,Y statement makes this entire program
redundant. Study the principle, however.
Subroutines can be used for plotting. If you recall our dog-plot, here
is an example of a subroutine used to fill the screen with dogs. The
subroutine for this is between lines 300 and 430 and is based on a grid
(8 horizontal by 5 vertical):
10 REM "DOGS"
20 FOR Х-й TO 50 STEP 10
30 FOR Ү-10 ТО 40 5ТЕР 10
40 GOSUB 300
239
45 NEXT Y
50 NEXT X
60 GOTO 700
300 REM **DOG PLOT**
310 PLOT Х,Ү
320 PLOT X+1,Y-1
330 FOR N=2 TO 4
340 PLOT X+2,Y-N
350 NEXT N
360 PLOT Х+3,Ү-2
370 PLOT X+4,Y-2
380 FOR N=1 TO 4
390 PLOT X45,Y-N
400 NEXT N
410 PLOT X46,Y
420 PLOT X+7,Y-1
430 RETURN
700 REM **END**
With plots of functions where the values of Y are not visible by
inspection, we can use the computer to ascertain them and derive the
appropriate scale factor.
For a function producing positive values of Y, we can use a routine
as below. We set À and B as the values of X between which we want to
plot the value of Y, and store the largest number encountered in a
variable MAXY. The routine is for the ZX81. Spectrum users would
need to use 240 in place of 60 (line 40), and 160 instead of 40 (line 80).
10 LET A-CMINIMUM VALUE OF X)
20 LET B=(MAXIMUM VALUE OF X)
20 LET МАХҮ=0
40 FOR Х=А TO Е STEP (Б-А2/60
SO LET Y=CFUNCTION OF X)
60 IF Y>MAXY THEN LET MAXY=Y
70 NEXT X
SO LET SY=40/MAXY
Adding the following lines gives us the plot:
20 FOR X=A-A TO B-A STEP (E-A)
160
100 LET YzX*X
110 PLOT X#é0/(B-AdsY#SY
120 NEXT X
Spectrum: 240 not 60 in line 90.
Notice that all the function values are calculated twice. It would be
neater to set up either two lists, or a two dimensional numerical array
(Х(60) and U(60) ог Х(2,60)), and store the values the first time
round. Try this when we have dealt with numerical arrays. Run the
program, using different values of X in lines 10 and 20 and some
different equations in line 5@ (and the same one in line 100). Try
X**2+3X, X**3 —6X + 2, etc. ( ^in place of ** if using Spectrum).
Revise the program to allow inputs in lines 10 and 20.
240
Q3: Movement and Timing
We can deal with the two topics of time and motion together. We will
introduce and illustrate the new functions concerned, and then look at
them in combination.
The first new commands (which only apply to the ZX81) are FAST
and SLOW. If the screen display is to be continuous, the ZX81 has to
read and print on screen the contents of the display file fifty times a
second (sixty times a second in the U.S.). It can then only compute in
the gaps between doing this. Up to now, we have used this continuous
compute and display mode exclusively. This is SLOW mode on the
ZX81. The Spectrum works in the equivalent of the ZX81 FAST
mode, and displays the screen at the same time:
SLOW allows a continuous screen display. Computations are
performed in the intervals between reprinting the screen.
SLOW may be used as a direct command or in a program line.
FAST blanks out the screen, and the ZX81 computes faster,
not needing to break off to display the screen. Screen display
is restored when
(i) the program ends
(ii) the program stops to await input
(iii) the program goes into SLOW mode
(iv) the program is instructed to PAUSE.
The screen display is updated during FAST, but only printed
at a break in the program.
FAST mode is used whenever it is necessary to perform a large number
of calculations on the ZX81, and a screen display is not vital. To
illustrate the two modes, enter and RUN this program:
10 SLOW
20 FOR X=1 TO 20
30 LET Z=X*X**X/X**X
40 PRINT Z;
50 NEXT X
Line 10 is redundant, the ZX81 will already be in SLOW mode. But
now change it to:
10 FAST
and RUN. Change it back and, by counting, see what the difference in
timing is between the two modes. You can also delete line 10, and shift
between the modes by using direct commands. Note the flash of the
screen when you input lines from the keyboard in FAST mode. This
241
makes it easy to tell which mode you are in. The ZX81 computer is
always in SLOW mode at switch on, and if you are shifting between
the two modes, using direct instructions, then the characteristic flash
will let you know if FAST is the current mode.
PAUSE
PAUSE causes the execution of a program to halt for the time
specified. The screen display is shown on the screen during
the PAUSE. Pressing a key during a PAUSE will cut the
PAUSE short and the program will continue.
PAUSE N gives a delay of N/50 seconds (N/6@ seconds іп
the U.S.)
PAUSE 150 gives a delay of 3 seconds (2% seconds in the
U.S.)
If N>32767 the PAUSE will continue until a key is pressed
on the ZX81.
If N = 0 the PAUSE will continue until a key is pressed оп
the Spectrum.
PAUSE allows us to insert a specific delay in a program. It also allows
p y prog
us to cause the program to wait for a key to be pressed before the
program will continue. The following program illustrates both these
functions:
10 PRINT "PROGRAM START"
20 PAUSE 100
30 PRINT "2 SECONDS"
40 PAUSE 100
50 PRIN'T "4 SECONDS"
60 PAUSE 200
70 PRINT "8 SECONDS"
80 PRIN' "NOW PAUSE UNTIL KEY PRESSED"
90 PAUSE 40000
100 PRINT "END"
Spectrum users must enter line 90 as 90 PAUSE 0.
PAUSE is useful in programs run in FAST mode on the ZX81, since
the display file is shown on the screen during a PAUSE, and we can use
this directly to get a screen display for a specified time.
PAUSE used the system variable FRAMES to count in units of
1/50th of a second (1/60th second in the U.S.). This is set by the a.c.
power supply frequency to the ТУ monitor, which governs the number
of times a second the screen display is refreshed, which is why the
timing varies in different countries.
When a PAUSE commences on the ZX81 the screen ‘flashes’. This
can be irritating. It can be avoided by use of an empty FOR...NEXT
loop, which does not produce this effect. The time delay is less precise,
but for non-timing functions — providing a delay whilst instructions are
read, for example - it is easily modified to suit.
242
10 PRINT "START"
20 PRINT "2SECOND DELAY"
30 PAUSE 100
40 PRINT "FOR...NEXT LOOP"
50 FOR X = 1 TO 150
60 NEXT X
74 PRINT "END"
The next instruction can be used in a program line by the ZX81 only.
It does not exist for the Spectrum. The definition and discussion apply
only the the ZX81, but the method of achieving the same effect on the
Spectrum is given below.
SCROLL
SCROLL moves the whole screen up one line, deleting the top
line, and sets a new PRINT position at the start of the new
bottom line.
To see this work, try this program:
10 FOR X-1 TO 10
20 PRINT X
30 IF X25 THEN SCROLL
40 NEXT X
We can use SCROLL to clear printout on the top of the screen, but we
must remember that if we use SCROLL the print position changes.
We can, however, use PRINT AT instructions to avoid the bottom line
print position. Delete line 20 in the above program and insert:
35 PRINT AT X, 0; X
Notice that we have to be careful of where we put SCROLL, and when
we use it. We can use it to prevent a ‘screen full’ error message, but
unless we want all lines rising from the bottom of the screen we have to
specify when to use it.
We can set a line to use SCROLL at the correct place:
10 FOR X=1 TO 50
20 PRINT X
30 IF X>21 THEN SCROLL
40 NEXTX
Scrolling on the Spectrum is automatic, the ‘scroll?’ prompt
appearing when the screen is full. When any key other than BREAK
and 'N' is pressed, the screen scrolls to display the next screenful of
information. To get the same effect as is produced by the ZX81
243
SCROLL instruction in a program, which can be useful, the procedure
on the Spectrum is as follows:
1. The value of — 1 must be POKEd into a system variable at memory
address 23692. This is done with a program line ‘POKE 23692, - 1’.
2. Something must be printed on line 21. This can be just a space, or it
may be the first thing you wish to print in a sequence that will have all
printing coming up from the bottom of the screen.
3. Scrolling will then occur, one line at a time, whenever another
PRINT instruction is given.
A simple program illustrates this:
10 POKE 23692, – 1
20 PRINT AT 21,0:“РКІМТ HERE TO CAUSE SCROLL”
30 PAUSE 50
40 PRINT “SCROLL”
50 PAUSE 50
60 PRINT “SCROLL AGAIN”
The PAUSE instructions merely cause а delay to enable you to see the
process properly. The PRINT item in line 20 could be a space, as long
as it is something printed on the bottom line. Try this program:
10 POKE 23692, -1
20 PRINT AT 21,0;° ” (Single space)
30 FOR F=1 TO 10
40 PRINT “РКІМТ”
30 NEXT F
We can use SCROLL, or the Spectrum equivalent, to create a moving
screen display. Try this:
For the ZX81 For the Spectrum
10 FOR Х-0 TO 30 STEP .3 10 FOR X =0 TO 30 STEP .3
20 LET L=15+14*SIN X 20 LET L=15+14*SIN X
30. PRINT TAB Ls "XX" 30 PRINT TAB L: “ZX.”
40 IF Х>6.3 THEN SCROLL 40 POKE 23692, – 1
50 NEXT X 50 NEXT X
Spectrum users please note also that the POKE instruction will work if
it is given as line 5 in the program, and line 40 deleted. Try it.
Try this for a rocket launch:
‘O PRINT АТ 18:17: "Em
ZO PRINT s "O"
30 PRINT ; ПЕШ”
40 PRINT +" ES:
90 FOR Гео TO 0 ЕТЕР -1
60 PRINT АТ ізің"
79 NEXT С
244
SO PRINT "ELASTOFF"
70 FOR X=1 TO 22
100 SCROLL
110 PRINT ж" V"
_ 129 NEXT X
Spectrum users need to delete line 100, and insert 85 POKE
23692, — 1.
Whilst on the subject of scrolling, here is a routine that scrolls a line
of text across the screen from left to right. Input a name (inverse
characters look better), or a line of text, and fill out the line with some
graphics characters. Lines 20, 50 and 60 fill up the line to 32 characters
with black squares. The technique can be used with several lines of
text, but is too slow to be useful if dealing with a full screen:
= REM *INFUT А NAME*
*(NICER IN INVERSE) #
е REM #REPEAT IF LINE NOT
*FILLEL*
10 INPUT A$
20 IF LEN A$432 THEN GOTO 60
20 PRINT AT 10:07A%
40 LET A$=AS( LEN ASI +АФС1 TO
LEN А%-1)
20 GOTO 30
ео LET A$-0$-"H"
70 HOTE 20
When you have keyed in the program, try deleting “АТ 10,0,” in line
30. This gives an effective full-screen display.
Games programs often utilise interactive graphics, via the INKEY$
function. A SKETCH program as below shifts the PRINT position
around. Note that on the Spectrum, INKEYS$ is not totally reliable.
Add PAUSE @ to ensure it works.
10 LET X=10
20 LET Y=10
ЗО PRINT RT ҮЧ, "+"
40 LET X=X-( INKEY$ ="3" AND
Х>О)+( INKEY$ ="S" AND X<31)
20 LET Y=Y-( INKEY$ ="7" AND
Ү>О09%( INKEYS ="6" AND Ү5219
60 GOTO 30
This uses logical values to do a multiple operation in lines 40 апа 50,
which both adds or subtracts 1 to the values of X and Y, and keeps the
character within the screen limits. This could be done less efficiently by
the following:
40 IF INKEY$ = ‘‘5’? AND Х>0 THEN LET X-X-1
50 IF INKEY$ = “8” AND X<31 THEN LET X-X +1
60 IF INKEY$ = “7” AND Y20 THEN LET Y-Y-1
70 IF INKEY$ = ''6" AND Y<21 THEN LET Y=Y+1
80 GOTO 36
245
Im lines 40 to 70 both conditions have to be true to execute the change
in the values of X or Y. In the original example, these logical tests are
combined (in the brackets) and use is made of the fact that the
computer uses 1 for TR UE and 0 for FALSE. These logical values are
used to change X and Y appropriately, according to which keys are
pressed, but only if the values of X are within 0 — 31 and the values of
Y are within 0 — 21 (i.e. within the PRINT AT range).
If, for example, X is equal to 0, then in line 40 above, the combined
conditions of INKEY$ = “5” (true, if it is being pressed) AND Х>0
(not true) will be false. The instruction following THEN will not be
executed. Similarly, in the line LET X = X - (INKEY$ = “5” AND
X20)-(INKEY$-2':8" AND X<31) each of the bracketed
expressions is evaluated for truth/falsity. Only one of the bracketed
expressions can be true, and if, for example, the first is true, X will
become X-(1(true)) + (0(false)). Logical operations, which are of
great importance, are fully covered in Section R.
We could add:
35 PRINTATY,X;' ”
to get a single character rather than a line of characters, but our
character flickers and is not on the screen very long.
A better way is to put the values of X and Y into two other variables,
and use these to store the position where a space is to be printed,
overprint as late as possible in the loop.
10 LET X-10
20 LET Y=10
30 PRINT AT YsX3"#"
35 LET А-Ұ
36 LET Б=х
40 LET X=X-¢ ІМКЕҮФ ="5" AND
Х>09%( ІМКЕҮФ z"E" AND X431)
50 LET ҮшҮ-( INKEY$ ="7" AND
Ү>024( ІМКЕҮФ ="&" AND Y<21)
55 PRINT AT AE;" "
&O GOTO 30
To get automatic movement, we need to use loops. Try this:
10 FOR X=25 TO 0 STEP - 1
20 PRINT AT І1,Х; “ай АТ 12, Хх; Se”
30 NEXT X
PAUSE 10 could be inserted as line 25 on the Spectrum to slow things
down a bit.
Our car moves, but it leaves bits of itself behind. Add a space after
each of the print strings, and the trail is automatically wiped out,
overprinted by the spaces.
246
10 FOR X=25 TO 0 STEP - 1
20 PRINT AT 11,X;“ „Ш "AT 12,X;' щн
30 NEXT X
The alternative, which is slower (and harder on the eyes), is to use
CLS, and reprint the screen. To see the effect, just add:
29 CLS
Or try this (which includes, to a rather distorted scale, a gravity effect)
and imagine you are Galileo:
1 REM GRAVITY DROP
10 LET Т-й
20 LET Н-й
30 PRINT AT 0,5; "MEN"
40 PRINT АТ 21,1; "----------- "
50 IF Н>21 THEN GOTO 110
60 PRINT AT Н,10; "*"
70 LET Т=Т+.25
80 LET H-INT 32*T*T/10
90 CLS
100 GOTO 30
110 PRINT AT 21,7; "*SMASH*"
The next program utilises graphics to illustrate the principle of the base
current flow through an NPN transistor. The flow of the main current
is indicated by a moving black graphic, and the flow of the base current
by a grey square. Study the program and analyse it so that you can
follow it. The string manipulation is quite complex. By now Spectrum
owners should have mastered converting ZX81 programs for their own
machines. Remember that the values PLOTted on the Spectrum
should typically be four times larger than on the ZX81 in order to get a
picture of a similar size. Apart from this, *Transim' should not present
any problems:
5 REM "TRANSIM"
10 PRINT "SIMULATION OF CURREN
T FLOW ІМ", "+УЕ BIASED NPN TRANS
ISTOR"
20 PRINT ss" PRESS 5 TO SWITCH
OFF BIAZ":"CURRENT FLOW IN BASE"
119 "PRESS R TO RECONNECT "
30 PRINT »» "GRAPHICS SHOW ELEC
TRON FLUOW":,:"HIT A KEY TO START
40 FALISE 4Е4
SQ CLS
во FOR Fz? To 49
70 PLOT Fo?
S0 PLOT F512
90 IF F276 THEN GOTO 120
100 PLOT 275F*3
110 PLOT 30,F+3
120 NEXT F
130 UNPLOT 29312
247
140 UNPLOT 27,12
150 PRINT АТ 95; "ж NEN TRANSIS
ТПЕ x": ТАБ Ss "eRe Уы X
ж!
160 PRINT АТ 5317: "BASE": AT 7:
17; "CURRENT ON"? АТ 14,2: "COLLEC
TOR": TAB 22? “EMITTER
170 FRINT АТ 5310; ““УЕ"; АТ 18%
OF +E = Мемма Р Мема -УЕ
120 REM *w*GFñFHIC STRINGS#*
170 LET A$-" BEBE BR ELE E ии"
200 LET $=" TTE E E TTE ы а
210 LET S$=" ú = mhi"
220 FOF N=1 TÜ 15
220 REM **GFñFHICS LOOPxx
240 FOR Fei TO 8
Qi IF F=1 THEN FRINT AT 7:14; "
260 PRINT АТ 16-Ез14: "B"
270 PRINT АТ 164: B$(F TO Fev;
ASIF TQ F+iG)
280 PRINT АТ 7313:5%(1 TO 3);
270 IF F=f AND ІМКЕҮФ ="S" THEN
200 PRINT АТ 73143" "b AT 16-F5
14$ s "H
310 NEXT F
320 NEXT М
330 PRINT АТ 2150; "PROGRAM HALT
ED. RESTART? CY OR N)"
340 INPUT ЕФ
390 IF R$ <> "Y" THEN GOTO 440
360 PRINT АТ 21:03"
370 GOTO 220
95, REM ж Ж А ХЕ Ж
жжБАСЕ CURRENT OFF СИ!»
400 PRINT АТ 5:10: “ " АТ 731
3:5%6(4 ТО); АТ 7:25; "OFF"
410 IF ІМКЕУ% <> "RE" THEN GOT
410
420 FRINT АТ 5310: "+VE"; АТ 731
2С6С1 TO: 22: АТ 725: "ON *
430 RETURN
52 КЕМ ** ENDSUB 339
HHH 553555555222
440 CLS
450 REM **END PROGRAM жж
Spectrum modifictions: PAUSE @ in line 40.
The program uses the ‘chunky’ ZX81 plot squares to draw the outline
(lines 60 to 140). Spectrum plot points could be used, but strings of the
graphics characters on keys 1 to 8 would be better. Refer to the screen
diagrams in Unit M2 for the positions on screen requiring printing.
248
Exercises
1. For ZX81 users: Computer performance in terms of speed is
compared by benchmark tests. Write a program that loops 500
times, performing a calculation each time. Run it in FAST and
SLOW modes, and time it.
2. Revise the left to right scroll to work right to left.
3. Write a program that draws a ship and moves it backwards and
forwards across the screen, automatically.
4. Revise the program to move the ship in response to INKEY$
input from the keyboard.
5. Write a program that uses PAUSE to display minutes and
seconds. Check the clock against a watch and improve the
accuracy.
Q4: The Display File
In order to talk about the display file, we must introduce some new
concepts, which are dealt with more fully in a later section of the book
(Section U).
The DISPLAY FILE is the memory picture of the screen
display stored in a sequence of memory locations or addresses
in the computer RAM.
BYTE. Each memory location in the computer stores an 8 bit
(digit) binary number which has a decimal value between 0
and 255.
To interact with the computer's memory, we use PEEK and POKE.
We are concerned here not with the general instructions (which are
dealt with in Section U) but with some specific uses for these
commands. We will give a definition of PEEK and POKE here, and
then discuss the use of these only in terms of some simple techniques
connected with the screen display that can be of use in graphics.
PEEK (M) returns the contents of the memory address (M) (a
binary number) in decimal form.
POKE (M),(N) inserts the value N (0 to 255) into the
specified memory address, M.
The display files of the ZX81 and Spectrum are organised very
differently. That of the Spectrum is much more complex, due to the
high-resolution PLOT screen and colour on the machine. We will deal
with the ZX81 display file in some depth below, and then describe the
Spectrum display file. Spectrum users should GOTO page 257, and
omit the ZX81 specific section below, unless they find it interesting for
249
general information. It is useful to know the ZX81 display file system if
you are Interested in converting ZX81 programs for the Spectrum, as
some programs use the techniques described below.
On the ZX81:
Each address of the display file stores in a byte a character
code, corresponding to the character to be printed on the
screen.
The display fille memory location differs according to the program
length, since it starts where the portion of memory occupied by the
program ends. For any given program the start location is constant.
The DISPLAY FILE start address is stored in the system
variable D-FILE, at memory locations 16396 and 16397.
For the display fille memory locations:
PEEK M gives a number (in decimal) which corresponds to
the character code located in the memory address M.
POKE puts into one of these memory locations a character
code.
POKE M, N puts the number (character code) N into
memory address M
The ZX81 has done away with much of the use of POKE in connection
with the display file, because the PRINT AT function actually uses a
routine in the computer that finds out where the display file starts and
then POKEs to it the required characters at the correct position.
To illustrate the work this saves, here is a program that puts ZX at
line 1, column 10, on the screen.
10 LET D = PEEK 16396 + 256*PEEK 16397
20 LET Z=D+(32+1+11)
30 -POKE Z, 63
40 POKE Z+1,61
Note that, even though we could write the routine above more
compactly (by missing out line 20 and using POKE D+ 44, POKE
D +45 as lines 30 and 40) it is still rather more complicated than:
10 PRINT AT 1,10; TZS?
Thus we will not use it unless we have good reason. But let’s run
through what we are doing. Do not worry if you cannot fully
understand all of this, you can return to this Section later, when the
memory has been covered.
250
Line 10 sets D to the values of the ‘D-FILE’ system variable, which
stores the memory location of the start of the display file. The address is
always stored in two bytes (16396 and 16397) of memory and the
second is the more significant byte (i.e. stores the higher value). Hence
the *256 before the second memory location.
PEEK 16396 + 256 * PEEK 16397 returns the value of the
memory location of the NEWLINE (ENTER) character at the
start of the display file.
Line 20 counts along the screen to the position required. The value of
44 has been broken down to show the principle. The D-FILE address
contains the NEWLINE (ENTER) character, which is always present
at the start of the first line. We count 32 for the spaces in line 0, and
then there is another NEWLINE (ENTER) character, marking the
end of line 0. We want the eleventh position (column 10) along the
next line, so we count 11. This gives us a value for the memory location
corresponding to the desired print position. Using this, line 3@ prints Z
Бу POKEing the corresponding character code into this location and
similarly line 4@ puts X in the next position along.
Notice that the display file has no correspondence to line and column
numbers, it merely numbers in sequence:
Start Column Newline (Enter)
Newline (Enter) Character
Character 0 1 1 "Dn. 31
(Line 0) 1 2 з ча 44, 33 34
jo 36 27 38... 66 67
MELOS) геу, Ga une ds a
(ipe 41) c 03) mecs tV VP SEN es {же vd 726 727
(Line 22) DEC 5052.45 759 760
(Line 23) Fe Goan CU; 5.22 792 793
So to use this technique we only need to find the start location of the
display file once, and allocate a variable to it (D in the program above),
or arrange to re-use a program line with the PEEK commands.
To try to make things a little clearer, try the following program:
10 LET DFILE = PEEK 16396 + 256*
PEEK 16397
20 PRINT “DISPLAY FILE START ADDRESS
І5”, MEMORY LOCATION ”; DFILE
30 FOR M=DFILE-8 TO DFILE + 8
40 PRINT M;TAB 10; PEEK M; TAB 18;CHR$ PEEK M
50 NEXT M
Line 10 PEEKs the D-FILE memory locations, which store the
number of the address in which the first NEWLINE (ENTER)
character of the display file is located.
If you have entered the program exactly as shown — including the
space after “Memory Location’’ - line 20 will print:
DISPLAY FILE START ADDRESS IS
MEMORY LOCATION 16694
This is followed by a printout like this:
16686 118 ?
16687 0
16688 50 М
16689 3 EN
16690 0 =
16691 243 NEXT
16692 50 M
16693 118 ?
16694 118 ?
16695 41 D
16696 46 Io
16697 56 S
16698 53 P
16699 49 L
16700 38 A
16701 62 Y
16702 0
This shows a memory address (16686) then the character code it
contains (118) and its character string (in this case 118 is NEWLINE
(ENTER), and prints a “?”). Address 16687 is a space (character code
0) and a space is printed. 16688 contains the number 50, which is the
line number of the last program line, and prints M. Then there is a 3
stored (which is the number of characters in the program line) and
which prints the graphic character, then NEXT (character code 243),
and M again, this time representing the variable М, not the number 50.
Then there is a NEWLINE (ENTER) character (118) marking the end
of the program. The next NEWLINE (ENTER) is at 16694, the start
of the display file, and then there are the codes and characters for
DISPLAY (the first words to be printed on the screen).
To illustrate the use of PEEK and POKE with the display file, here
is a program to draw on the screen. This does essentially the same
thing as the sketch program we met earlier, but it uses the technique of
POKEing characters to the display file directly, instead of via the
PRINT AT function. We give a full listing here, but in fact to run it,
you need only enter lines 190 to 290.
292
10
20
30
290
300
The complex looking line 280 (be careful to input it correctly) uses the
same logic as was mentioned with the ‘‘Sketch’’ program. If you
inspect it, after we’ve dealt with logic properly, you will see that each
key that is pressed gives a different value. The equivalent lines without
this technique would be:
280
281
282
283
284
285
286
287
REM “ARTIST"
PRINT “DRAWS A PICTURE BY M
OVING A CHARACTER IN 8 DIRE
СТІОМ5"
PRINT "ТО MOVE IN THE FOLLO
WING DIRECTIONS PRESS THE C
ORRESPONDING KEY"
PRINT TAB 10; "NORTH--W"
PRINT TAB 10; "SOUTH--X"
PRINT TAB 10; "EAST--D"
PRINT TAB 10; "МЕЅТ--А"
PRINT TAB 10; "NORTHEAST--E"
PRINT TAB 10; "SOUTHEAST--C"
PRINT TAB 10; "SOUTHWEST--Z"
PRINT TAB 10; "NORTHWEST--Q"
PRINT
PRINT
PRINT "TO CHANGE THE CHARAC
TER PRESS S THEN THE CHARAC
TER THEN NEWLINE"
PRINT
PRINT "DON'T GO OVER THE ED
GE OF THE SCREEN"
PAUSE 400
CLS
LET T2120
LET А5-"%"
POKE PEEK 16396+PEEK 16397*
256+T,CODE А5
IF INKEYS="" THEN GOTO 250
LET BS=INKEYS
LET T=T+(32 AND B$z"Z")- (33
AND BS="X")+ (34 AND B$="C"
)- (34 AND B$z"Q")- (33 AND
B$="W")- (32 AND В$="Е")+(
1 AND BS="D")-(1 AND B$="
A")
IF BS="S" THEN INPUT AŠ
GOTO 246
ТЕ В5-"2" THEN LET T=T+32
IF BS="X" THEN LET T=T+33
IF BS="C" THEN LET T=T+34
IF В5-"О" THEN LET T-T-34
IF BS="W" THEN LET T-T-33
IF BS="E" THEN LET T=T-32
IF BS="D" THEN LET 'Т=Т+1
IF В5-"А" THEN LET Т-Т-1
253
-33
-34 32
= +1
+32 +34
+33
If you look at the diagram above and the numbering of the display file,
you will see how it works. — 1 or +1 move the position along a line,
- 34 moves it up one line and to the left etc. All this numbering is
within the display file. Line 240 PEEKs the D-FILE memory
locations, adds the display file position number and POKEs into the
result (a memory address in the display file) the character code for A$.
Notice the speed of this program. This gives us one reason to use
PEEK and POKE: to provide speed of display.
Notice the warning about the edges of the screen in the program
listing. When you have decided you have played with the program
enough, try going off the edge of the screen. The results will not harm
the ZX81, but you will probably have to switch the power off to reset
the computer. All manipulations of the display file must be done with
great care so as not to interfere with the NEWLINE (ENTER)
characters marking the end of each line. If these are altered the
computer cannot keep track of where everything should be, the display
will go crazy and the program will crash. Be warned! (And be careful in
your programming!)
It is possible to increase the screen size of the display to give the
capability to PRINT or PRINT AT on the bottom lines of the screen.
The system variable (DF-SZ) at memory location 16418 holds the
number of lines in the bottom half of the screen, and is normally set at
2. If we use POKE 16418,0, the bottom two lines can be used to
PRINT AT. Try this program.
10 POKE 16418,0
20 - POR L = @ TO 23
30 PRINT “LINE NUMBER” ;L
40 NEXTL
50 FOR X =1 TO 300
60 NEXT X
Notice that, after the delay caused by the FOR...NEXT loop, the 0/60
message appears on the bottom line as usual, and that the next
command from the keyboard clears the bottom two lines. This is
254
because DF-SZ returns to its normal value on completion of a
program. If we use COPY it will also not print the bottom two lines - it
is only set for a normal screen size of 22 lines.
We may also restrict the screen size. Key in this program:
10 POKE 16418, 28
20 PRINT “TOP LINE"
30 PRINT “SECOND LINE"
40 PAUSE 158
50 PRINT "NOW SCROLL"
60 FOR Х-1 ТО 4
70 SCROLL
80 PRINT "SCROLLED ";X
90 МЕХТ Х
The SCROLL instruction now operates from the bottom line of a
screen which is only 4 lines deep. This can be used to clear just the top
part of the screen, leaving the rest undisturbed.
Try this next program, which uses both these techniques together.
(You don’t need to input the text in lines 70, 90 and 110. Just PRINT
1, 2 and 3 instead).
10 POKE 16418,0
20 FOR L=0 ТО 23
30 PRINT "LINE NUMBER ";L
40 NEXT L
50 POKE 16418,21
60 SCROLL
76 PRINT "THESE LINES"
80 SCROLL
90 PRINT "NOW CLEARED AND "
100 SCROLL
110 PRINT "REST OF SCREEN LEFT
AS IS"
120 FOR Х-1 TO 300
NEXT X
If entered as above, the top portion of the screen would look like this:
THESE LINES NOW
CLEARED AND REST OF
SCREEN LEFT AS IS
LINE NUMBER 3
LINE NUMBER 4
LINE NUMBER 5
LINE NUMBER 6
Unfortunately, we cannot choose a screen section in the middle of the
screen (e.g. lines 6, 7 and 8) to do this with, and must use PRINT AT
“(32 spaces)’’ with the lines we want to clear, or overprint directly, or
POKE spaces into the relevant positions, as in this program:
10 FOR F= 1 TO 9
20 PRINT "LINE NUMBER ";F;"
(16 SPACES) END"
30 NEXT F
255
40 PRINT "LINE NUMBER TO BE
CLEARED ?"
50 INPUT LINE
60 LET DFILE-PEEK 16396+256*PE
EK 16397
70 FOR X-1 TO 32
80 POKE (LINE-1) *33+DFILE+X,9
90 NEXT X
Note that if we put:
70 FOR X=32TO1STEP -1
we get a reverse line clearance (right to left), and
70 FOR X=32 TO 30 STEP - 1
clears END, but leaves the rest of the line.
Another useful system variable concerned with the ZX81 display file
is the DF-CC address, locations 16398 and 16399. This holds the
address of the current print position in the display file. If this address is
found by using PEEK 16398 + 256* PEEK 16399 then it can in turn be
PEEKed, and will give the code of the character present at the current
print position. Note that the current print position is the next position to
be printed. A line like
10 PRINT TAB8; “А”
leaves the current print position set at the start of the next line of the
display, and
19 PRINT TAB 8; A":
gives as the current print position the next position after the A. To
illustrate, here is a variation on the basic screen movement program we
derived from SKETCH which uses the DF-CC variable.
10 LET Х-10
20 LET Ү-10
30 PRINT АТ Ү,Х;
40 LET D=PEEK 16398%256%РЕЕК 16399
50 PRINT "*"
60 LET Х-Х-(ІМКЕҮ%-"5" AND X>@)
+ (INKEYS="8" AND X<31)
70 LET Ү-Ү-(ІМКЕҮ5-"7" AND Y>@)
+ (INKEYS="6" AND Y«21)
80 POKE D, @
90 GOTO 30
Instead of setting two variables as equal to X and Y before their values
are altered (before line 50) in order to identify where to print the space
which blanks the ‘‘*’’, we use variable D to store the location of the
print position (line 40) and then POKE a 0 (space) into it to overprint
(line 80).
256
Notice lines 30 and 40. We must set the PRINT AT position in line
30, then PEEK the DF-CC addresses, then PRINT the ‘‘*’’.
The ASTEROIDS program in the program library uses the
technique of PEEKing the next PRINT position to determine whether
a black square occupies this position. The relevant lines are
130 PRINT AT 5,C;
140 IF PEEK (PEEK 16398 + 256*PEEK
16399) = 128 THEN GOTO 250
150. PRINT 44”
Look up the program апа work out how these lines relate (о the rest of
the program. If you find line 140 confusing, remember that the ZX81
evaluates expressions in brackets first. It gets the value stored in the
16398/9 addresses, which returns the address of the PRINT position,
then PEEKs this address.
We will now deal with the Spectrum display file, which does not
have the straightforward structure of that of the ZX81, and to which
PEEK and POKE techniques have little application.
SPECTRUM DISPLAY FILE
The Spectrum display file is organised in a very different way to that of
the ZX81. This is a consequence of the high-resolution screen display
on the Spectrum (256 * 176 points are plotable), compared to the
‘chunky’ graphics of the ZX81, with only 64 * 44 plot squares. The
pattern of squares in any character cell on the ZX81 can be defined as a
character code. On the Spectrum each individual point of the 8 by 8
grid of a character cell must be individually specified.
The Spectrum display file is fixed in memory, and does not vary its
location. There is no need to PEEK a system variable to find its
position, as the start address is always 16384, and it is a fixed length of
6144 bytes, occupying the memory addresses up to 22527.
The complex method of organisation means that it is not possible (as
it is with the ZX81 and other computers), to POKE character codes to
the screen and have the character specified by that code appear.
Similarly, we cannot PEEK the screen to find out what character, if
any, occupies a given location. Both these operations are theoretically
possible, with much calculation, but not practicable. However, the
speed of the Spectrum’s operations takes away much of the advantage
of using PEEK and POKE on the ZX81, and we can use PRINT AT
instructions to place characters on the screen, and two special
Spectrum functions for finding out what is on the screen. Before
introducing these instructions, here is a description of the way the
Spectrum display file is organised:
Each character cell has an 8 by 8 dot matrix of points, which may be
‘set’ (blacked or inked in) or not. These patterns of dots make up the
257
characters. We'll treat this in more detail later. For plotting, each point
must be specified individually, and this means that the characters
available in the character set do not cover the whole set of possibilities
for each cell. To cope with this, the Spectrum stores each pattern of
points along a 32 character cell line on the screen in a sequence of
bytes. However, these are not stored in sequence down the screen. The
top point sequence of each of the first eight rows of characters (lines)
are stored one after the other. The second line of points in each of these
8 lines of characters is then stored, and so on until the first eight lines of
the screen display have been defined. The next eight lines on the screen
are then stored in the same way, followed by the bottom eight lines of
the 24 line screen.
To make this clearer, key in the following program and run it:
10 FOR A= 16384 TO 22527
20 POKE A, 85
30 NEXT A
This puts into each byte the binary form of 85 (01010101), giving
alternate plotted and unplotted (‘set’ and ‘unset’) points. You will see
that the top line of points for each of the top eight lines on the screen
appears, in sequence top to bottom, then the second line of points for
each of these eight PRINT lines, and so on. When this sequence has
finished, it repeats for the next block of eight lines, and then again for
the bottom eight.
You should now see why it is not easy to define a particular sequence
of POKEs to the display file to get a character on screen! This is best
done using PRINT AT on the Spectrum in all cases. Pixels can also be
plotted, of course, and in Section W the user-defined graphics available
on the Spectrum are dealt with, which enables any character cell
pattern of 8*8 plot points to be defined and treated as a character which
can be placed on the screen with a PRINT AT instruction.
To find out what is on the screen at a particular place we use
SCREENS (instead of PEEKing the display Ше) on the Spectrum.
SCREENS
SCREENS is a Spectrum specific function. It returns the
single-character string of the character printed at the specified
line and column co-ordinates. It has the form:
SCREENS (L,C)
PRINT SCREENS (2, 6) returns the character printed at Line
2, Column 6 on the screen. The brackets cannot be omitted.
SCREENS will return the true video form of any inverse
character. It does not recognise either the true video or
inverse video forms of the Graphics characters.
250
Note the restriction on what SCREENS will recognise. The chunky
graphics characters on keys 1 to 8 are not recognised. An empty string is
returned. Run the following program to see SCREENS$ in action. After
you've tried other characters, try the graphics characters and inverse
video. Input PRINT LEN SCREEN$(10,10) as a direct command to
see that the null string (no characters) is returned.
10 INPUT A$
20 PRINT AT 10, 10; A$
30 PRINT SCREENS (10,10)
There is another Spectrum specific instruction that can be used to find
out what is currently on the screen. This is POINT.
POINT
POINT returns 1 if a specified PLOT pixel is inked in (‘set’),
Ø if it is not. It has the form
POINT (X,Y)
where X and Y are the PLOT screen co-ordinates of the point
to be checked.
To see the action of POINT to check if a plot pixel has been inked in,
key in the following:
10 PLOT 128,88
20 PRINT POINT (128,88)
30 PRINT POINT (128,89)
POINT returns 1 for line 20 (pixel plotted), and 0 for line 30 (pixel not
plotted, or ‘unset’). Notice that the brackets must be placed around the
X and Y expressions. Both POINT and SCREENS will, of course,
work with calculated values. POINT can be used to give information
about inverse characters that SCREENS will not provide. We can
illustrate this simply. Key in this program:
10 PRINT “EP
20 PRINT POINT (0,175)
30 PRINT AT 10,10; Ml"
40 PLOT OVER 1;84,90
50 PRINT POINT (84,90)
60 PRINT POINT (85,90)
Line 20 checks the upper left corner pixel of the character cell with the
exponentiation sign printed in inverse video. This returns 1, since the
pixel is set. Line 30 prints an inverse square (CAPS SHIFTed graphic
259
8), which SCREENS will not recognise. Line 40 unplots 1 pixel, using
the OVER 1 statement, and line 50 checks this plot point, returning 0,
since it is unplotted, and line 60 checks roughly the centre point of the
black square, which returns 1. This offers us a way of checking inverse
characters. You must, of course, make the correct calculations for the
transfer from the PRINT to PLOT screens.
You should notice two points for future use, after Section W has
introduced the other Spectrum functions not dealt with in the main
body of the text. One is that we referred to POINT returning 1 if the
pixel was set or inked in, and when you start using colour, you should
remember that POINT checks for the currently specified INK colour.
For our purposes, this is black. The other is that the colour attributes
that refer to a character cell when colour is used can be another source
of information about the screen display. (This uses the ATTR
function. See Unit W3.)
260
SECTION R: LOGICAL OPERATIONS
R1: Logic Values and Numeric Values
When using the logical capability of Sinclair BASIC we must
distinguish between logical values and the numeric values produced by
logical evaluation. We have touched upon this earlier in the book, but
deferred a full explanation until now.
LOGICAL VALUE is the value of an expression using the criteria:
any non-zero value of the expression = ‘‘TRUE”’
a zero value of the expression = ‘‘FALSE”’
When an expression is logically evaluated it is assigned one of two
numeric values:
“TRUE” 1
“FALSE” 0
R2: Boolean Operators: The AND Operator
AND A
Examples 100 IF (A = 10) AND (B<>3) THEN GOTO 60
200 PRINT (A AND B)
The AND operator (symbol ^ ) forms a logical conjunction between
two expressions involving conditional operators.
If both expressions are ‘‘TRUE”’ the conjunction is “ТЕСЕ”.
If one or both are ‘‘FALSE”’ the conjunction is ‘‘FALSE?’’.
The numeric value of “TRUE” is 1.
The numeric value of “FALSE” is 0.
All non-zero values аге “ТЕСЕ”,
In line 100, if the relation A = 10 is “ТЕГЕ” and the relation B<>3
15 “TRUE” then control will pass to line 60. If either or both of the
relations is ‘‘FALSE”’’ then control passes to the next line.
In line 200 the computer will not print A + B. It will print the value of
A or 0 depending on the values of A and В.
Remember: All non-zero values are “TRUE”.
So if
A = 15 and B = 6
A = “ТЕСЕ” B = “TRUE”
So the relation (A AND B) is (“ТКСЕ” AND “ТКСЕ”).
So the result is logically “TR UE”.
15 is printed.
If A = 16 (“TRUE”) and В = 0 (zero value – logically
“FALSE’’).
Then (A AND B) is ((TRUE" AND ‘‘FALSE”’’) =“ FALSE” = 0.
So @ is printed.
We will explain this in more detail later.
261
Truth Table for AND
A | > [sees
| TRUE |
A
TRUE
A and B are conditional expressions.
R3: The OR Operator
OR V
Examples 100 IF (A>1) OR (B = 0) THEN STOP
200 PRINT (C OR D)
The Boolean operator OR (symbol v ) forms the logical disjunction of
two expressions involving conditional operations.
If either or both of the expressions is “TR UE” the OR disjunction is
"IRUE'".
If both expressions are ''FALSE"'' the OR disjunction is ‘‘FALSE’’.
In line 100 if either of the expressions (A21) and (B = 0) аге
“TRUE” the program will STOP.
If both are **FALSE'' control passes to the next line.
In line 200 if C2 10 = '"TRUE'" and D= 0 = "FALSE"
С OR D=“TRUE” OR “FALSE” = ““TRUE”’
10, the value of C is printed.
If C=@ = “FALSE” and D = 0 = “FALSE”
C OR D= “FALSE” OR “FALSE” = “FALSE”
So @ is printed.
Truth Table for OR
TRUE TRUE TRUE
TRUE FALSE TRUE
FALSE TRUE TRUE
FALSE FALSE FALSE
A and B are conditional expressions.
R4: The NOT Operator
NOT `]
Examples 20 IF NOT A THEN STOP
30 IF NOT (A = B) THEN STOP
100 PRINT NOT A
262
NOT (symbol | ) logically evaluates the complement (reverse) of a
given expression.
In line 20, if A210 then A=‘‘TRUE”’ апа NOT А = NOT
“TRUE” = “FALSE”.
So in line 20 if A is 10, NOT A is “FALSE” and control passes to
the next line.
IfA=@ ("FALSE') then NOT A= NOT “FALSE” “ТЕСЕ”
and the program stops.
In line 30 if (A= B) is “FALSE”, NOT (А = В) = NOT “FALSE”
= “ТКСЕ”, so program stops.
In line 100 1А = 0 = ‘‘FALSE”’ then NOT А = “TRUE” = 1
So 1 is printed.
If A= 29 then A is “ТКГПГЕ” and NOT А = ‘‘FALSE’’, and 0 is
printed.
Truth table for NOT
TRUE FALSE
FALSE TRUE
A is a conditional expression.
R5: Conditional Operators
‘There are two ways to use conditional operators in logical evaluations.
1. ‘To check the numeric value of an expression
Examples 100 IF A= 3 THEN GOTO 60
200 IF B<>C THEN STOP
The numeric value produced by the logical operation is not important.
We are concerned only with the truth or falsity of the condition
indicated іп the IF... THEN statement, which determines whether the
instruction is executed. When the specified condition is present
("TRUE"), the statement after THEN will be carried out.
2. То check on the numeric value produced by logically evaluating ап
expression
In this case we want the numeric values, where ‘“TRUE’’=1 and
"FALSE' = 0
Examples 200 PRINT A<B
300 PRINT A=3
The PRINT statement used as above will give the numeric values
produced by logical evaluation.
Line 200 is evaluated as a logical expression, so that if it is TRUE
263
that A is less than B, 1 will be printed, and if A is equal to or bigger
than В, the expression is false and 0 will be printed.
Line 300 is interpreted by the BASIC as: “Print 1 if = 3, 0 if A
does not equal 3.”
The numeric value of the logical evaluation is distinct from the
logical value of the expression.
R6: Logic Operations on Conditional Expressions
IF (CONDITION AND| CONDITION) THEN...
IF (CONDITION) THEN...
The effect of the logical operators AND, OR and NOT on
conditions which are TRUE or FALSE gives a result which is
TRUE or FALSE and on which the IF...THEN instruction
acts accordingly.
EXAMPLES:
100 IF(A>10) AND (B= 0) THEN GOTO 20
200 ІЕ(А-0) OR (В-0) THEN STOP
300 IF NOT (А = В) THEN PRINT ‘‘A<>B”’
These all mean:
IF [combined result is TRUE] THEN (do it)
IF [combined result is FALSE] go to the next line of the program.
Using logical operations is a way of combining conditional operators in a
statement. For example:
IF [(condition 1) AND (condition 2) AND (condition 3)]
evaluates as TRUE or FALSE] THEN...act accordingly.
60 IF ((A>B) AND (C>A) AND (D>C)) THEN STOP
AND
IF (CONDITION 1) AND (CONDITION 2) THEN (RESULT)
TRUE TRUE TRUE
TRUE FALSE FALSE
FALSE TRUE FALSE
FALSE FALSE FALSE
EXAMPLE:
Condition 1- My age is > 12 years
Condition 2- My age is < 20 years
Result – І am a teenager.
IF (my age > 12 years) AND (my age < 20 years) THEN (I am a
teenager).
Program
10 PRINT “INPUT AGE”
20 INPUT A
264
30 IF (A>12) AND (A<20) THEN GOTO 60
40 PRINT “YOU ARE NOT A TEENAGER”
50 STOP
60 PRINT “YOU ARE A TEENAGER”
OR
IF (CONDITION 1) OR (CONDITION 2) THEN (RESULT)
TRUE TRUE TRUE
TRUE FALSE TRUE
FALSE TRUE TRUE
FALSE FALSE FALSE
EXAMPLE:
Condition 1 — I earn wages
Condition 2 — I get pocket money
Result – I have money
IF (I earn wages) OR (I get pocket money) THEN (I have money).
Program
10 PRINT “INPUT AMOUNT OF WAGES AND POCKET
MONEY YOU GET”
20 INPUT W
30 INPUT P
40 IF (W»0) OR (P>0) THEN GOTO 70
50 PRINT “YOU HAVE NO MONEY”
60 STOP
70 PRINT “YOU HAVE”’;W + P;‘‘POUNDS”’
NOT
IF [NOT (CONDITION)] THEN (RESULT)
TRUE FALSE
FALSE TRUE
EXAMPLE:
CONDITION - I have money
RESULT — I do not have money
IF [NOT (I have money)] THEN (I don’t have money)
Program
5 PRINT “ARE YOU A LIAR?”
10 PRINT “ІМРІУТ AMOUNT OF MONEY"
20 INPUT M
30 IF NOT (M>0) THEN GOTO 60
40 PRINT “APPARENTLY YOU DO NOT HAVE MONEY"
50 STOP
60 PRINT “YOU DO HAVE MONEY REALLY ?"
265
R7: Multiple Logic on Conditions
Multiple logical operations on conditions are often useful.
They take the form:
AND AND AND
IF [(C1) = | (C2)] к= | [(C3) ке | (C4)] THEN...
Where СІ = Condition 1
C2 = Condition 2
Condition 3
C4 = Condition 4
e.g. IF [(C1 AND C2) OR (СЗ AND С4)] THEN...
The above statement means that:
IF conditions 1 AND 2 are obeyed
OR conditions 3 AND 4 are obeyed
then the combined expression is TRUE, and the instruction
will be executed, i.e. either pair of conditions being both
TRUE will give the result.
IF (С1 AND C2) AND (C3 AND C4)] THEN
In this statement all four conditions must be true to give the
result.
e
оз
I
What do the following imply?
IF [(C1 OR C2) AND (C3 OR C4)] THEN...
IF (Сі OR C2) OR (C3 OR C4)] THEN...
Notice the importance of brackets in the statements.
Their placing gives a clear logical meaning to an expression. Any
bracketed expression will be evaluated first. The result (““TRUE”’ or
"FALSE") obtained from the bracketed expression will be used in
evaluating the whole expression.
A practical example of multiple logical operations on conditions
would be obtaining a loan. The relevant conditions could be:
C1 = Husband is over 21 years old
C2 = Husband's salary is over £5,000 per year
C3 = Wife is over 21 years old
C4 = Wife's salary is over £5,000 per year.
We can write a statement which indicates whether the bank will grant
the family a loan to buy a car:
IF (Сі AND C2) OR (C3 AND C4)] THEN loan granted.
Exercises
1. Key in and run the program which illustrates this:
10 PRINT "INPUT AGE OF HUSBAND"
20 INPUT HA
30 PRINT “INPUT AGE OF WIFE"
40 INPUT WA
50 PRINT "INPUT P.A. INCOME OF HUSBAND"
50 INPUT IH
266
70 PRINT “INPUT P.A. INCOME OF WIFE"
80 INPUT IW
99 IF (НА>21 AND IH>= 5000) OR
(WA>21 AND IW>= 5000) THEN GOTO 120
100 PRINT "NOT ELIGIBLE FOR LOAN"
110 STOP
120 PRINT "LOAN AVAILABLE"
2. Write a program which inputs four numbers and outputs a
message if any of them are zero.
R8: Logical Operations on Numbers
The logical operations AND, OR, NOT when applied to numbers
return a number as the result. The rules for the operations on two
numbers X and Y are given in the following truth tables. Non-zero
values may be either positive or negative.
AND
i.e. X AND Y returns X if Y is non-zero
0 if Y is zero.
i.e. X OR Y returns 1 if Y is non-zero
X if Y is zero.
i.e. NOT Y returns @ if Y is non-zero
1 if Y is zero
EXAMPLES:
7AND3 = 7
7 AND 0 = 0
ЭШК Л = |
267
JORO = 5
NOT 8 = 0
NOT @ = 1
Exercises
1 Key inthe examples given above as direct commands, and verify
the rules of logical operations on numbers.
2 Keyin and run the following programs:
LOGIC 1:
5 REM "LOGIC 1"
10 INPUT A
20 INPUT B
30 PRINT "А=";А,"В="; В
40 PRINT "A AND B-";A AND B
50 PRINT "A OR В=";А OR B
60 PRINT "NOT B=";NOT B
70 GOTO 19
Results:
А-77 В
A AND B=77
А ОК В = 1
NOT В = 0
li
н>
сл
А = 77 В =Q
А AND В = 0
А OR В = 77
NOT В =1
LOGIC 2:
5 REM "LOGIC 2"
10 REM **THIS PROGRAM TESTS THE LOGICAL OR
OPERATOR ACTING ON A NUMBER AND A
CONDITION TOGETHER**
30 PRINT "Ү-10%(7 OR А=3) "
35 PRINT
40 PRINT "INPUT A VALUE FOR A PLEASE"
45 PRINT
5@ INPUT A
55 LET Ү-10%(7 OR A=3)
60 PRINT "IF A=";A,"THEN Ү-";Үү
65 PRINT
70 PRINT "WHAT ARE YOUR CONCLUSIONS??"
75 PRINT
88 PRINT
90 GOTO 39
LOGIC 93:
2 MEM “LOGIC 3"
10 INFLT А
20 FRINT 77-(10 AND A=)
30 GOTO 10
268
R9: Priority
OPERATOR PRIORITY
= & >, «аб, ll 5
NOT 4
AND 3
OR Ж
Priority rules are strictly obeyed. If brackets are not used properly
when logical operators act on conditions the desired result will not be
achieved. For example:
NOT (**FALSE'' AND ‘‘FALSE’’)
gives NOT “FALSE”
= “TRUE”
BUI
NOT “FALSE” AND “FALSE”
gives “TRUE” AND ‘‘FALSE”’
= “FALSE”
Completely the opposite!
Exercises
1 Key and and run this program, which checks priority.
10 LET A=1
20 LET B-1
30 PRINT NOT (A - 0 AND B = 0)
40 PRINT NOT A-0 AND B- 0
2 What result would the following give?
PRINT 5 AND 3 OR 0 OR NOT 7 AND 4
3 Key in and run program ''LOGIC 4”, which tests priorities:
REM "LOGIC 4"
REM **THIS PROGRAM TES'TS MU
LTIPLE LOGIC OPERATORS**
10 LET A-5 AND 3 OR @ OR NOT 7
мл
AND 4
20 PRINT "5 AND 3 OR @ OR NOT
7 AND 4="; A
30 PRINT
40 PRINT
50 LET B=((4 AND 2) AND МОГ (0
AND 3)) OR ((3 OR Ø) AND (4
OR 0))
60 PRINT "((4 AND 2) AND NOT (
0 AND 3)) OR ((3 OR 0) AND
(4 OR 0))-";В
269
R10: Logical Operations with Strings
1 Logical operations using AND, OR and NOT may be
performed on conditional string expressions. For
example:
10 IF (A$ = B$) AND (C$ = D$) OR (D$ = E$) THEN...
50 PRINT NOT AS = BS.
2 The AND operator may be used directly between a string
and a number. For example:
PRINT (A$ AND N)
The result of this operation is given by the truth table.
——
< ECA W
EF | ULE
i.e. A$ AND N returns A$ if N is non-zero
and a null string if N is zero.
3 Two strings cannot be directly operated on by any logical
operator because strings cannot have logical values. For
example:
A$ AND B$, A$ OR B$, NOT A$
are meaningless expressions.
Exercises
1 Key in PRINT NOT “A” =p
апа PRINT YA” = B” AND “BM = G” OR "G'a"E"
to test the rules of logical string operation. Try other
combinations.
2 Write a program which requests a name and then checks to see if
it corresponds to several strings stored in the program, printing
out a message to say if the word was found.
3 Write a program to test the truth table for A$ AND N.
R11: Logical Operations Between Strings and Conditions
Only the AND operator may be used.
The rule is the same as for strings and numbers.
A$ AND C gives A$ if C is “ТЕСЕ”
A$ AND C gives a null string if C is “FALSE”
C can be either a string condition or a numeric condition.
270
EXAMPLES:
PRINT “А” AND 3 =3 gives A
PRINT “А” AND 3 = 4 gives the empty (null) string
PRINT “А” AND “В” = *B" gives А
PRINT “A” AND “B” = “С” gives the null string
Exercises
1
R12:
Key in and run LOGIC 5, which illustrates string and condition
use.
5 REM "LOGIC 5"
10 LET Х5-”АВ”
2) LET YSe"Ac*
30 PRINT (2 AND X$»Y$)
40 PRINT (7 AND X$«Y$)
50 PRINT (5 AND X$-Y$)
52 PRINT
54 PRINT
60 LET Р5-"1"
70 LET Q$="2"
80 PRINT (33 AND PS$>Q$)
90 PRINT (66 AND Р5<05)
100 PRINT (99 AND Р5-06)
102 PRINT
110 PRINT «со я ABUEL ниди м
112 PRINT
120 PRINT "AND mW que uu SW
Results:
Soc © < Sd
SO "VAM “АСТ”
AND vy] tte eet
Alter the values of X$, Y$, P$ and O$ and run the program again
each time.
Alter the program to allow various strings and numbers to be
input, and print out the relationships.
Logical Operations Between Numbers and Conditions
N AND C
N OR C
271
Where N is a number
and C is a condition:
either a string condition e.g. A$ = “A”
or a numeric condition e.g. B = 7
N FALSE 0 N
These are the same rules as with logical operations between
numbers.
N AND C gives N if C is “ТЕГЕ”
N AND C gives 0 if C is “FALSE”
N OR C gives 1 if C is “ТЕГЕ”
N OR C gives N if C is “FALSE”
Exercises
1 Analyse, key in and RUN the following statements, and confirm
the rules.
PRINT TANDA = “A~
PRINT P AND “A” = “А”
PRINT 7 AND ‘‘A”’ = “В”
PRINT 0 AND “A” = “ВБ”
PRINT 7 OR “A” = “A”
PRINT 0 OR “A” = “А”
PRINT 7 OR “А” = “p”
PRINT 0 OR “А” = “В”
2 Кеуіп and run this program.
Input B as 3 and 5.
10 INPUT B
20 PRINT 7 AND B= 3
30 PRINT 7 OR B=3
40 GOTO 10
R13: Applications of Logical Operators
Simple conditional tests
Multiple conditional tests
Multibranch GOTO and GOSUB
Finding maximum and minimum values
Checking characters input
Checking input values
Testing for zero
Default values
COND Qo GON m
1
2
4
Simple Conditional Tests
IF (Logical Operation) THEN (statement).
If the logical operation is TRUE the statement is executed.
AND, OR and NOT operators are used.
Multiple Conditional Tests
IF [(Condition 1) AND (Condition 2) OR (Condition 3)] THEN
(statement).
If the multiple logical operations are TRUE the statement is
executed.
AND, OR and NOT are used.
Multibranch GOTO Routines
Using this technique, control may be transferred to any of a
number of statement lines.
Here we use the AND routine, whose default value is zero:
GOTO (100 AND C1) + (200 AND C2) + (300 AND C3)
C1, C2 and C3 are three conditions.
Control is transferred to line 100 if C1 is TRUE
200 if C2 is TRUE
300 if C3 is TRUE.
Similarly:
GOSUB (100 AND C1) + (200 AND C2)
Control is transferred to:
the subroutine at line 100 if C1 is TRUE
200 if C2 is TRUE
300 if C1 and C2 are TRUE
and the next line, if neither are true.
Key in and run this program:
10 INPUT A
20 INPUT В
30 GOTO (100 AND А=0)+ (200 А
ND B=)
40 PRINT A48
50 STOP
100 PRINT "A-Q.INPUT A AND B
AGAIN"
110 GOTO 10
200 PRINT "В-0.ІМРОТ B AGAIN"
218 GOTO 20
300 PRINT "BOTH ZERO. INPUT A
AND B AGAIN"
318 GOTO 10
Finding Maxima and Minima Values
We use the AND operator to find the maxima and minima of
two numbers X and Y.
1@ INPUT X
20 INPUT Y
30 PRINT "MAX IS"; (X AND X>=Y)
+(Y AND Y>X)
40 PRINT "MIN IS"; (X AND X<=Y)
%(Ү AND Ү<Х)
273
or we could program this as
20 IF X >= Y THEN GOTO GO
40 PRINT "MAX="3¥:" MIN="3X
FQ TUF
æ
ео PRINT "MAX=";X;" MIN="sy
Which do you think is the best method?
Finding the largest number in a list is another application. We
have a list of numbers A(1) to A(N). We can compare the first
two, A(1) and A(2), and put the largest of these into a variable L
by the statement:
LET L-(A(1)AND A(1)> = A(2)) +(A(2)AND А(2)>А(1))
We compare this value of L with the next number A(3) and
make L take the larger value of the two and so on through the
list.
LET L=(L AND L> = A(3)) + (A(3) AND A(3)>L)
The program asks us to input how many numbers will be in our
list (N). We then input the numbers A(I). These are printed on
the screen together with the largest value. Two loops are used,
the first to input the numbers and the second to perform the
comparisons.
10 REM "LARGEST"
20 PRINT "INPUT HOW MANY NUMBE
30 INPUT N
40 PRINT М
50 DIM A(N)
60 FOR I = 1 TON
70 INPUT A(T)
80 PRINT A(I);" ";
98 NEXT I
100 LET L =(A(1)AND А(1)>=А (2)
)+(A(2)AND А(2)> А(1))
1102 FOR I = 3 TON
120 LET L = (L AND L>=A(I)) +
(A(I)AND A(I)> L)
130 NEXT [I
148 PRINT “LARGEST NUMBER IS "
;L
Key in and run the program.
This is an appropriate place to emphasise the care needed in
programming logical operations. There are two things that
cause problems. The first is the setting of conditions, and the
second is the grouping of these conditions in a logical sequence
that will produce the required result. Any line the computer does
not reject because of a syntax error will produce a result. Care is
needed to get the right result.
This can be illustrated by the question of deriving the larger of
two numbers, using AND. The problems of non-rigorous use of
the logical and relational operators can be illustrated by
considering the following problem. We have two numbers X
27%
and Y. We know that AND can be used so that if we code a
program line as LET M = X AND Х>Ү it will return the value
of X if the condition is true. We want to use this to get the value
of a maximum. The line above will produce zero if the condition
Is not true. So we can combine two such tests in one line to get
our maximum. We key in this sort of program (do it):
10 INPUT X
20 INPUT Y
30 LET MAX =X AND Х>Ү +Y AND Ү>Х
40 PRINT MAX
Input some numbers and check the results.
Something is wrong. Looking at the program, we see we need
some brackets. As it stands, line 30 is actually a sequence of
three conditions, joined by two AND operators. It reads ‘give
MAX the logical value of (X) AND (X>Y + Y) AND (Y>X)’.
Since all three conditions have to be true for the whole
expression to be true, and since (X>Y + Y) and (Y>X) cannot
both be true, we get zero.
We make the expression more sensible, we hope, by changing
line 30 to read: LET MAX = X AND (Х>Ү) + Y AND (Y>X).
Key in this as a new line. Now try some inputs.
If X is smaller than Y we get the value of X printed, and if X
is greater than Y we get zero. We haven’t got the brackets right.
There are still three conditions joined by two ANDs. We've
changed the meaning, but not to what we actually want. If X
and Y are non-zero, (X) is true, ((X>Y) + Y) is zero for smaller
X, one (TRUE) for larger X, added to Y. This is non-zero, so is
TRUE. If the last condition is TRUE (i.e. Y2X) then the
combined expressions give X as the result. If it’s FALSE then
the whole expression is FALSE and prints 0. Now we see what's
wrong, we can put some more brackets in.
Edit line 30 to read: LET MAX = (X AND(X>Y)) + (Y AND
(Y>X)).
Now try some inputs. The greater of the two numbers is
returned, which zs what we wanted. If we now look at our
working line, we can see (or should) that there are brackets we
don’t need, although they don’t do any harm. Edit line 30 to
read LET MAX = (X AND X>Y)+(Y AND Ү>Х) and check
the greater value is still returned. So we're finished — or are we?
Only if you didn't consider what happens if the numbers X and
Y are equal. Input the two numbers as the same value and see
what result you get. Both expressions are FALSE if the numbers
are equal, so we get zero printed.
The line should read: 30 LET MAX = (X AND X» = Y) «(Y
AND Y>X). Just in case you're not convinced of the problems
you can get into if you are not careful, enter the line as above
and check that it works. Then edit it to read: LET MAX = (X
275
5
AND X> = Y)+(Y AND Y> = X) and input values with X>Y,
YX and X= Y.
This sort of problem is only avoided by carefully thinking out
the result required in the case of all inputs, and checking the
logic before you code it in. If there are these possible problems in
a four-line program, think of the potential pitfalls in a complex
one!
Checking Characters Input
Control in a program can be achieved using the INKEY$
statement and checking which character is keyed in using
combined conditional logic operations. We have seen this used
in programs earlier in the text.
The following program enables the numbers on the keyboard
to be used as a Joystick, allowing you to move a dot in any
direction on the screen.
To move the dot in the following compass directions press the
desired key.
4 7 1
5 8
3 6 2
= REM "JOYSTICK"
10 REM *SPECTRUM: X=120) Y-80
20 LET X-30
30 LET Y-20
40 PLOT X,Y
50 IF ІМКЕҮФ ="" THEN GOTO 50
80 LET A$- ІМКЕҮФ
45 REM *SPECTRUM:
70 OVER 1:PLOT X«Y
70 UNPLOT X,Y
75 REM *SPELTRUM: Х<255
80 IF Х<63 AND CA$="S" DR Аф="
1" OR Аф="2") THEN LET X=X+1
SỌ IF X50 AND (A$-"A" DR A$="2
" OR A$-"5") THEN LET X-X-1
95 REM *SPECTRUM: Y£175
100 IF Y442 AND (A$="7" DR A$="
4" ПЕ Аф="1") THEN LET Y=Y+1
110 IF Y50 AND (A$="6" DR A$="2
" ОЕ A$z"3") THEN LET YzY-1
120 GOTO 40
276
Analyse the program.
Key it in and run it.
Change the program to move the dot in larger Jumps.
Change the program to move the dot in sixteen different
directions.
Checking Input Values
The OR operator can be used to check that values keyed into a
program are in range. For example, we are asked to input values
for variables in the following ranges:
A range 0-9
B range 10 - 99
C range 100 - 999
Here is a program that checks values input:
10 INPUT A
20 IF A<@ ОН A»9 THEN GOTO 100
30 INPUT B
40 IF 8<10 OR B>99 THEN GOTO 2
00
50 INPUT C
60 IF С<100 OR C>999 THEN GOTO
300
70 PRINT АТ 1,1;А; AT 1,8;B;A
T 1,15;C
80 STOP
100 PRINT "INPUT A OUT OF RANGE"
110 GOTO 10
200 PRINT "INPUT B OUT OF RANGE"
210 GOTO 30
300 PRINT “INPUT C OUT OF RANGE"
310 GOTO 50
Testing for Zero
We can use the NOT routine to check for zeros in a list of
numbers.
NOT (N) = 0 when N<>0
NOT (0) = 1
Here is a program which sets up a counter C, initialises it, and
requests numbers to be input. If a zero is input NOT 0 = 1 and
C is incremented by LET C = C + NOT (A(F)).
5 DIM A(19)
10 LET С-й
20 FOR F = 17010
30 INPUT A(F)
35 PRINT A(F);" ";
40 LET C=C+NOT (А(Е))
50 NEXT F
60 PRINT "THERE ARE";C;"ZEROS"
Key in and run the program.
Default Values
The default value of AND is zero. AND is therefore extremely
useful in the addition of logical operations. For example:
60 GOTO (100 AND A= 0) + (200 AND A»0).
277
The default value of OR is 1. OR is thus useful in the
multiplication of logical operations.
For example, the following program asks you to input any
three digits in the range 0 – 9. The computer will generate three
digits at random.
You win £10, £100 or £1000 depending on how many digits
you guess correctly.
= REM "“GUESSANLM"
10 DIM ACI)
20 DIM BCS)
20 PRINT “INPUT 3 DIGITS IN TH
E RANGE 0-9 ONE АТ A TIME"
40 FOR F=1 TO 3
ФО INFUT ACF)
ео PRINT ACF" "3
70 LET E(CF2-2 INT € REND *10)
SO NEXT F
vo PRINT
100 PRINT БСО?" ";B(2»);" "SBCs
à
110 LET Z=(10 OR (Aci) <> Bei)
)%(1O ПЕ CACZ) <> B(2)))*(10 OF
(ACS) <> Beso)
120 IF Z=1 THEN LET Z=0
130 PRINT “YOU WIN "32
140 INFUT AS
150 IF АФ-"Ү" THEN GOTO 20
160 STOP
278
SECTION S: LISTS AND ARRAYS
S1: Dimension
The dimension statement DIM is used to reserve storage space
for a LIST or ARRAY to contain numbers. DIM A (N) sets up
an array A with space for N numbers.
A may be any single letter A to Z. The Spectrum will accept
both upper and lower case letters, but a(N) will signify the
same array as A(N).
N may be a number, a numeric variable or an expression.
A dimension statement must be declared before the array can be used.
This is usually done at the beginning of a program, unless the value of
N is to be set equal to an expression or variable which will be calculated
later in the program.
There may only be one DIM statement on a line for the ZX81.
These statements in a program:
10 DIM А(10)
20 DIM B(15)
30 DIM C(30)
will reserve storage for a list A containing 10 numbers, a list B
containing 15 numbers and a list C containing 30 numbers. The values
of each ELEMENT (number) in an array are automatically set
(initialised) as zero.
Error code 4 (‘out of memory’ on the Spectrum) will be displayed if
there is no room for the array, i.e. if N is too large.
S2: Index Variable
The index variable N is used to locate a member of a list.
We use the form A(N) to locate the N'th number of a list
A(L), where 1< = N< = L.
If N = 5, then A(N) refers to A(5), the fifth number in the
list.
The program below establishes a four element list, so that:
A(1) = 1
A(2) = 4
A(3) = 9
A(4) = 16
and then prints out the second and fourth element.
10 DIM A(4)
20 FOR N=1 TO 4
30 LET A(N) - N*N
40 NEXT N
50 PRINT “SECOND ELEMENT IS ”; A(2)
60 PRINT “FOURTH ELEMENTIS ”; А(4)
279
S3: Lists
Many types of problem involve a set of values and it is convenient to
store such items in a list. The next program illustrates the idea. We
assume a list of the squares of the first 20 integers is required. It is
necessary to reserve storage for the twenty numbers (1, 4, 9 etc., up to
400) and this is done in line 20. The loop (lines 30 to 50) puts A(1) = 1,
A(2) = 4...A(20) = 400 and it is thus possible to use any item of this list
at a later date, using the index variable.
Line 60 prints out 4 16 36 and the loop (lines 80 — 100) will print out
the complete list of numbers.
tO REM "LIST"
20 DIM A(20)
30 FOR N=1 TO 20
40 LET A(N)=N*N
SO NEXT N
60 PRINT AC2):" "rACAD;" "j
ACE)
70 PRINT
80 FOR N-1 TO 20
90 PRINT ACN)
100 NEXT N
S4: Examples of Lists
We give below some example programs illustrating the use of lists.
1 Simple allocation of elements in а list. Look at the program.
What will be printed out when the program is RUN? Check by
entering and running the program.
REM *LIST1"
DIM A(4)
LET A(1)=19
LET A(2)=58
LET A(3)=72
LET А(4)-20
PRINT A(1)*A(3)
PRINT
PRINT A(3)-A(2)
2 Allocation of values to the elements in a list using a loop and the
INPUT statement. The value of the control variable (N) of the
loop is used to specify each element of the list in turn. Again,
work out the results of the program, then check by keying it in
and running it.
REM "LIST2"
DIM A(4)
FOR N-1 TO 4
PRINT "TYPE A(";N;")"
280
50 INPUT A(N)
60 NEXT N
70 PRINT A(1)*A(3)
80 PRINT
99 PRINT A(3)-A(2)
3 АП lists used in a program must be dimensioned, with each
dimension statement on a separate line. Hand trace this
program and decide what the 10 elements in list B(N) are. Check
by entering and running the program.
5 REM "LIST3"
19 DIM А(20)
20 DIM B(10)
30 FOR N-1 TO 20
40 LET A(N)=N*N
50 NEXT N
69 FOR N-1 TO 10
70 LET B(N)-A(2*N)-A(2*N-1)
80 NEXT N
90 FOR N-1 TO 10
109 PRINT B(N)
110 NEXT N
4 А variable may be used in a DIM statement, provided its value
Is assigned before the DIM statement is reached. Enter program
“LIST4”. Run the program for X = 20.
= КЕМ “LISTA”
10 INFUT X
ZO DIM A(X)
20 FOR N=1 TO X
40 LET АСМ) = FRR N
eO PRINT ACN)
60 NEXT М
5 The program “ОНМ5 LAW?” illustrates the use of lists to store
data from a set of electrical circuit experiments. The voltmeter
and ammeter readings from each experiment are stored in the
lists A(N) and V(N) as they are input. Notice that it is essential
to dimension storage space for the derived list of results, R(N),
(line 60). The loop (lines 90 to 140) enables the readings to be
stored for use in the later loop (lines 180 to 220), which performs
the calculation and prints out the results of each experiment,
giving the current in amps, the voltage in volts, and the
resistance in ohms derived by the formula, R = V/I in line 190.
Line 179 initialises a variable T which has each resistance in
turn added to it. This enables line 250 to print the average
resistance value.
10 REM “OHMS*LAW"
28 PRINT "OHMS LAW RESULTS"
30 PRINT "UP ТО 20 PAIRS OF R
EADINGS"
40 DIM А(20)
50 DIM У(20)
60 DIM R(20)
201
70
80
90
100
110
120
130
140
150
160
170
180
190
200
210
220
230
240
250
PRINT "TYPE NUMBER OF SETS
OF READINGS"
INPUT X
FOR N=1 TO X
PRINT "TYPE CURRENT IN AMPS"
INPUT A(N)
PRINT "ТҮРЕ VOLTAGE IN VOLTS"
INPUT V(N)
NEXT N
PRINT "AMPS"; TAB 8; "VOLTS";
TAB 16; "OHMS"
PRINT U*#*#*kkkkkkkkkkkkkkkkk
***k
LET Т-й
FOR N-1 TO X
LET R(N) =V(N) /A(N)
LET T=T+R (N)
PRINT A(N);TAB 8;V(N);TAB 1
6;R (N)
NEXT N
PRINT U**kkkkkkkkkkkkkkkkkkk
ТР
PRINT
PRINT "AVERAGE RESISTANCE "
:Т/Х;" OHMS"
Notice that if lines 70 and 80 had come before the DIM
statements,
we could use DIM A(X), etc. to set the size of the
arrays exactly, as in program LIST4 above.
6 А similar type of program is shown below. This shows image
positions (V) and magnifications (M) for a convex lens, given
the focal length of the lens (F) and the object distance (U).
5 REM "CONVEXLENS"
10
PRINT "THIS PROGRAM SHOWS THE POSITION AND
MAGNIFICATION OF ‘THE IMAGE PRODUCED BY A
CONVEX LENS"
PRINT V e e ee eee eee eee dec dee dee ee e e de e Ax (n
DIM U(12)
DIM V(12)
DIM M(12)
PRINT "TYPE FOCAL LENGTH IN CM."
INPUT F
PRINT "TYPE OBJECT DISTANCE IN CM."
FOR N-1 TO 12
INPUT U(N)
LET V(N)=U (N) *F/ (U (N)—F)
LET M(N)-V (М) /U (N)
NEXT N
PRINT "U";TAB (8);"V";TAB (22); "M"
FOR N-1 TO 12
PRINT U(N);TAB (8);V(N);TAB (22);M(N)
NEXT N
The screen display will look like this:
282
THIS PROGRAM SHOWS THE POSITION
AND MAGNIFICATION OF THE IMAGE
PRODUCED BY A CONVEX LENS
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
M
U
10 -13,333333 “143353333
20 -40 “2
30 -120 -4
39.555 -3555.5056 -89.887639
40.555 2922.8829 72.072073
50 200 4
60 120 2
70 93.333333 1.3333333
80 80 1
90 72 0.8
100 66.666667 0.66666667
120 60 0.5
S5: String Arrays
The DIM statement for string arrays has the form
DIM A$ (N,L)
where N = number of strings and L = the fixed length of each
string. A may be any single letter A to Z, but must NOT be
the same as a simple string variable. Each string is set to
contain L spaces initially.
DIM A$(3,4) will reserve storage space for 3 strings
A$(1),A$(2),A$(3), each of length 4, in the string array А8.
Each letter of each string can be accessed separately, as with a string
variable. A$(2,3) will return the third character of the string A$(2).
Substrings may also be allocated by a statement such as A$(2,1 TO 2),
which will return the first and second characters of A$(2). For example,
if A$(2) = “EFGH' then:
A$(2,2 TO 4) = “FGH”
The two programs below show these operations. Key them in and run
them. Note that spaces may be included as letters, as can any other
characters useable in a string.
If we have:
20 DIM А%(2.28)
20 LET A$i025z"AEDC Еж G"
Шеп АФ(2%40-" "
апа АФ(2:35 TO Ез-"Еж G"
1) 5 REM "STRING*ARR1"
10 DIM А5(4,3)
15 PRINT "ТҮРЕ ІМ LETTERS THRE
E AT A TIME"
20 FOR N=1 TO 4
30 INPUT AS(N)
40 NEXT N
50 PRINT A$(4,3) ;" ";A$(3,2)
70 PRINT
80 PRINT A$(1);" ";A$(2);" "; А
$ (3)
283
2) 10 REM "STR*ARR2"
20 DIM AS(3,4)
30 LET A$(1)="ABCD"
40 LET A$(2)="EFGH"
38 LET AS(3)e"IJEL"
50 PRINT A$(2,4) ;" ";A$(3, 2)
70 PRINT
80 PRINT AS(2,2 TO 4)
90 PRINT
100 PRINT А5(1,3 TO 4)
S6: Two Dimensional Arrays
A 2-D (two dimensional) numeric array is dimensioned by the
statement:
DIM A(R,C)
where À is any letter, R is the number of Rows and C is the
number of Columns.
All elements are set as zero.
The simple array is one-dimensional, and contains just a linear
sequence of items. Arrays can have more than one dimension:
4 6 8
10 12 14
16 18 20
22 24 26
This is a numeric array consisting of £ rows of numbers in 3 columns.
Storage would be reserved by the statement:
10 DIM A(4,3).
In an array A(R,C) we can access any element, so that in the array
above:
A(2,1) = 10 A(3,2) = 18 etc.
An array of two (or more) dimensions is also known as a MATRIX
(plural matrices).
The following program establishes an array and prints out two
selected elements and then the complete array:
“0 REM "ARRAY"
20 DIM А(10:9)
20 FOR R=1 TO 10
39 FOR Cel TO F
40 LET ACR» CO ZEXC
30 NEXT C
60 NEXT Е
70 PRINT Ас10%62»АС2%32
Бо РЕІМТ
зо FOR К=1 TO 10
100 FOR C=1 TO 7?
110 PRINT TAB S#Cr ACE C33
120 NEXT С
120 РЕІМТ TAE 4;
140 NEXT К
Line 20 allocates the appropriate storage. Nested loops (line 30 — 60)
are used to allocate values to the elements in the array. Line 70 prints
284
out two elements in the array. Nested loops (line 90 to 140) print out
the complete array.
Why is line 130 required?
In order to keep track of the elements of an array we need to have a
system. In general it is easiest to use R to represent the Rows and C the
Columns and to always access the rows before the columns.
Note the use of the TAB function to give a clear printout.
]
2
3
2 3
4 6
6 9
8 12
10 15
4 5 6 7 8 9
8 10 12 14 16 18
16 20 24 28 32 36
20 25 30 25 40 45
etc.
String arrays can also have more than one dimension.
2-D String arrays are dimensioned by a statement of the form
DIM A$(R,C,L)
where R is the number of Rows, C is the number of Columns
and L is the length of all strings in the array.
Try this program:
10
20
30
40
50
60
65
70
80
99
100
110
120
130
REM "2DSTRING"
DIM AS (3, 3,53
PRINT "TYPE WORDS 5 LETTERS
OR LESS"
FOR R-1 TO 3
FOR C=1 TO 3
PRINT АТ 2,0;"ROW ";R;" COL ";C
INPUT AS(R,C)
NEXT C
NEXT R
FOR R-1 TO 3
FOR C-1 TO 3
PRINT AT R*4,C*8;AS(R,C)
NEXT C
NEXT R
Key this in and run it. Try some appropriate entries for the rows and
columns, as the routine in line 60 gives a cue for which entry is next.
This is a useful routine for use with multiple entry INPUT routines,
since it is very easy to forget which entry 1s next. One run of this
program gave a final screen display like this:
285
TYPE WORDS 5 LETTERS OR LESS
ROW 3 COL 3
START 2ND THIRD
FOUR FIVE SIXTH
SEVEN EIGHT FINAL
Note also line 110, where both control variables of the nested loops are
used to format the printout using the PRINT AT instruction.
87: Multidimensional Arrays
Multidimensional arrays are available for both numbers and strings,
although a 3-D string array is rarely something needed in a program!
The easiest way of thinking of these arrays is as follows:
A (P, R, O) is a 3 dimensional array: page, row, column
А (B, P, R, C) is a 4 dimensional array: book, page, row, column.
A 5 dimensional array would be a library, on the basis of this analogy.
These arrays require DIM statements to reserve the necessary storage.
A simple example of a 3 dimensional array (which needs 3 nested
loops) is given below.
10 REM "3DLIST"
100 DIM A(3,2,4)
110 FOR P-1 TO 3
120 FOR R=1 TO 2
130 FOR C=1 TO 4
140 LET A(P,R,C)=P*C*R
150 NEXT C
160 NEXT R
170 NEXT P
180 PRINT A(2,1,3)
190 PRINT
200 FOR Р=1 TO 3
210 FOR R=1 TO 2
220 FOR С-1 TO 4
230 PRINT A(P,R,C);" ";
240 NEXT C
245 PRINT
250 NEXT R
255 PRINT
260 NEXT P
The similar program below, extended by a dimension, shows a 4
dimensional array printed out in a suitable form.
286
10 REM “4DARRAY"
100 DIM A(2,3,4,5)
110 POR B=) TO 2
126 FOR P=1 TO 3
130 FOR R=1 TO 4
140 FOR Cz] TO 5
150 LET A(B,P,R,C) B*P*R*C
160 NEXT C
170 NEXT R
180 NEXT P
190 NEXT B
200 PRINT А(1,2,3,4):" ";A(2,2,3, 3)
210 PRINT
220 POR В-1 ТО 2
230 FOR Р-1 TO 3
235 PRINT "BOOK";B;"/PAGE";P
240 FOR R=1 TO 4
250 FOR C=1 TO 5
260 PRINT A(B,P,R,C);" “>
270 NEXT C
280 PRINT
290 NEXT R
300 PRINT
310 NEXT P
320 PRINT
330 NEXT B
Here's a 3-D string version to try. Input only two letters at a time.
Actually it doesn't matter, the computer will ignore any characters in
excess of 2, since that 1s the dimensioned length.
5 REM "3D*STR*ARR"
10 DIM A$(3,3,3,2)
20 FOR P-1 TO 3
30 FOR R=1 TO 3
40 FOR C=1 TO 3
50 INPUT AS$(P,R,C)
60 NEXT C
70 NEXT R
80 NEXT P
90 FOR P=1 TO 3
100 FOR R=1 TO 3
110 FOR С-1 TO 3
120 PRINT АТ R*3, (P*10-10)4C*3;
AS (P, R,C)
130 NEXT C
140 NEXT R
150 NEXT P
Work out how the PRINT AT expressions work.
$8: Use of Arrays
A simple example of the use of 2-D arrays is shown in the seat booking
program below. A small theatre consists of 10 rows of seats with 6 seats
in each row. Some seats may already be reserved. These are input
when the program is run. When a new booking is made the requested
seat, if available, is sold. If the seat is not available a seat in the same
row is offered. If no seat in that row is available the customer is asked
to choose another row.
287
The sections of the program are as follows:
1
4,2
4.3
Initialise an array to represent the 10 rows of 6 seats (line 30).
All elements in this array are 0, and represent unbooked seats.
Input seats already booked (lines 40- 130).
Input row and seat number of booked seats. If input is @ for the
row number, program goes to 2.3.
If seat already booked (array element = 1), print message to
user. Seat is booked by placing a 1 in the appropriate array
element.
Program prints prompt, then halts until C is input.
Customer request for seat is input (lines 165 ~ 240).
Row and seat required are input. If seat already booked (array
element = 1), program goes to 4.
Seat is booked.
Menu is printed to enable user to choose to book another seat,
or to view seating plan.
If seat booking is requested, program returns to 3.1. If seating
plan option is chosen, program goes to 5.
Seat unavailable module (lines 300 - 450).
Seat unavailable message is printed, then the variable SEATS
is set at zero, and the loop checks if at least one seat is free in
this row, setting SEATS = 1 if a seat is free (Current Row R,
checked for S(R,1) to S(R,6)).
If no seats are free in this row (SEATS = 0), program passes to
line 440 and prints message, then returns to menu (3.3).
If at least one seat is free, the loop at lines 390 to 410 prints out
the numbers of the seats free, and the program returns to the
menu.
View Seat Plan Module (lines 500 — 600).
Nested loops are used to display seat plan, row 10 being at the
top, as 078 and 175.
Copy option is given, to print out seating plan.
Menu presented for end of program or return to book seats.
Program goes to 3.1, or proceeds to 6.
Program ends. Instructions given to restart if required without
using RUN and clearing the data stored in the array.
10 КЕМ “THEATRE”
20 REM ##INITIALISE ARRAY ++
30 DIM 2С(10%442
35 REM **xINSERT SEATS ALREADY
жжрГІІКСЕТІ ж
40 FRINT "INFUT SEATS THAT ARS
BOOKED, “a "INPUT О TO FINISH"
S0 FRINT "ROW?"
60 INPUT F
70 IF R=O THEN GOTO 130
80 PRINT "SEAT?"
зо INFUT C
288
100 IF 5(ҒаГ2с1 THEN PRINT "ROW
"Е" SEAT "FCs" ALREADY": “BOOK
ЕП "
110 LET 5(КзГ2т1
120 GOTO 50
ізо ELS
140 PRINT “INPUT C TÜ PROCEED T
Q BOOKING. "
150 INFUT АФ
160 CLS
165 REM w*CUSTOMEF REQUEST FDF3
Xx EAT X%
170 PRINT "ТҮРЕ ROW RERUIRED"
120 INFUT F
170 PRINT "TYPE SEAT NUMBER"
200 INFUT C
210 IF SctR»C)=1 THEN GOTO 300
220 LET S(R»C)=1
230 PRINT “THIS SEAT FREE. NOW E
ODKED. "
240 PRINT "ROW "Е" SEAT "С
250 FRINT
260 PRINT “BOOK ANOTHER SEAT (S
ӘСЕ VIEW", “SEATING PLAN CFO ТІМЕН
T $ OR P"
270 INFUT АФ
280 IF Ag="S" THEN GOTO 170
290 GOTO 500
300 FEM ** SEAT UNAVAILABLE жж
310 PRINT “REQUESTED SEAT NOT A
VAILABLE"
320 LET SEATS=0
330 FOR N=1 TO 6
340 IF ЕСЕ» М) =1 THEN GOTO 360
350 LET SEATS=1
360 NEXT N
370 IF SEATS=0 THEN GOTO 440
380 PRINT "SEATS FREE: ";
390 FOR М=1 TO 6
„200 IF S(R|N)=O THEN FRINT М; "
410 NEXT N
420 PRINT "."
430 GOTO 450
440 PRINT "ND SEATS ARE FREE IN
ROW “FR
450 GOTO 260
490 REM s* SEATING FLAN жж
500 CLS
510 FOR R=1 TO 10
520 LET X=11-R
530 PRINT TAB 8: "ROW "FX; TAB 1
S40 FOR C=1 TO 6
550 PRINT SCX)?
560 NEXT С
570 FRINT
580 NEXT F
289
590 PRINT +s+s"INPUT C TO COPY ñN
Y TO PROCEED”
600 INFT AS
610 IF A$z"C" THEN COPY
620 PRINT аз "INPUT E TO ЕМІЗЕ T
О BOOK SEATS."
630 INFUT АФ
640 IF A$-"E" THEN GOTO 670
650 CLS
660 GOTO 170
670 PRINT "PROGRAM STOPPED. US
GOTO 170 ТО", "RESTART. "
630 STOP
690 REM ** END PROGRAM жж
Screen display, at end of seat plan print routine (the first prompt has
been responded to with a user input):
ROW 10 000000
ROW 9 000000
ROW 8 000000
ROW 7 000000
ROW 6 000000
ROW 5 000000
ROW 4 000100
ROW 3 100000
RW. 2 дылы
ROW 1 000000
INPUT C TO COPY,ANY TO PROCEED
INPUT E TO END,S TO BOOK SEATS.
The variables used in the theatre booking program are as follows:
S(10,6)
SEATS
“THEATRE” - DATA TABLE
Array to store 10 rows of 6 seats (value 1 when seat
booked, 0 when free).
Current Row of array in processing.
Current Seat number in processing.
User Input string for menu choices.
Marker used to indicate whether seats are free in current
row. Set to 0 when no seats free, 1 when seats available.
Loop variable. Value used in processing inside loops to
check seat availability, and print seat numbers.
Loop variable used to print seat plan. Note this is the
same name as the variable for Rows above. This name
may be used in two different ways in this program because
the value of the simple variable R is re-initialised by the
input at line 17@ on return to the seat selection routine.
Variable used for reverse printing of seating rows.
290
C Loop variable for seats in seat plan printing. As with R
above, re-initialised as simple variable on return to seat
selection routine.
Note that the use of variables in two ways, as with R and C in this
program is only possible if the simple variables will be re-initialised
every time they are used, otherwise problems can arise. A loop variable
erases a simple variable of the same name. It would be better practice
to use different names for the two types of variables.
291
SECTION T: SORTING SEARCHING AND STORING ARRAYS
T1: Searching and Sorting
Searching a list of numbers (or strings) for specified values can
obviously be done much more efficiently if the numbers (or strings) are
sorted according to some specified order, commonly alphabetical order
or ascending numerical order. In electronic data processing groups of
records (files) can be handled more efficiently if the records are pre-
sorted into a specified order (e.g. by merging transaction files into a
master file). Various techniques have been developed to sort data and
several of the simpler methods are illustrated in this section together
with two simple methods of searching lists.
There is a considerable difference in the efficiency of the various
sorting techniques depending on the type and volume of data to be
sorted. A technique which is good for a random list of numbers may
not be appropriate for a list in which only one number is out of
sequence. For random lists the Quick Sort and Shell Sort techniques
are very much faster than a Bubble Sort. Deciding on which is the most
suitable method is largely a matter of experience and you should
experiment using the different techniques for equivalent sets of
numbers, timing the sort procedures.
Many sorting algorithms exist, and we will first deal with the
simplest.
The BUBBLE SORT is used for sorting numbers (or strings with
appropriate alterations) into ascending or descending order. The
principle of the bubble sort is to compare adjacent numbers and change
positions if they are in the incorrect order. This is done for elements 1
and 2, then 2 and 3, 3 and 4..Х-1 to X at the end of which the
highest number is in the Xth position. This is repeated (and the next
highest number bubbles up to the X ~ 1th position) and repeated
again, until the ordering is complete.
The following program is a bubble sort to put numbers into
ascending order. The sorting routine itself 1s in lines 130 to 225.
10 REM "BUBBLE"
20 PRINT "TYPE NUMBER OF ITEMS
TO BE SORTED"
25 PRINT "MAXIMUM NUMBER 50"
30 INPUT X
35 IF Х>50 THEN GOTO 25
40 DIM A(50)
60 PRINT "TYPE NUMBERS ONE AT
A TIME"
75 LPRINT "UNSORTED LIST"
80 FOR №] TO X
90 INPUT Z
100 LET A(N)-Z
110 LPRINT A(N) ;" ";
120 NEXT N
125 LPRINT
292
130 REM **SORTING ROUTINE****
140 FOR N-1 TO X-1
150 FOR M-1 TO X-N
160 LET C=A(M)
170 LET D=A (M+1)
180 IF C<=D THEN GOTO 210
190 LET A(M)=D
200 LET A(M+1)=C
210 NEXT М
220 МЕХТ М
225 REM ******gND SORT******
230 LPRINT "SORTED LIST"
249 FOR N=1 TO X
250 LPRINT A(N);" ";
260 NEXT N
Sample printout:
UNSORTED LIST
129 267 56 41 69 43 99 90 4 8
SORTED LIST
4 8 41 43 56 69 90 99 129 267
То illustrate (һе operation of the program, we'll take the first four of
these numbers and see how the program sorts them:
Bubble sort for 4 numbers A(1), A(2), А(3), A(4)
inputas L29, 26/, 530, 41
Procedure:
(1) Go through the list comparing successive number
pairs. For example:
A(1) and A(2), then A(2) and A(3).
If А(1)>А(2) then they are swapped so that A(2)
becomes A(1) and A(1) becomes A(2). If A(1)
<A(2) then they are left as is.
We see that the largest number in the.list will
finally be in the highest position, 1.e. A(4).
(2) On the first pass we make three comparisons and
the largest number will end as A(4).
On the second pass we make two comparisons,
and the largest number will be in position A(3).
On the third pass we make one comparison.
The larger number will be A(2).
No need for any more passes. Smallest number
will be A(1).
There are four numbers: so X - 4
We need X - 1 passes: so N = 1 TO(X- 1)
= 1 TO 3 passes
For each pass we need from 1 to X — N comparisons:
so M = 1to(X- N) comparisons
Here is a diagram in table form of the operations performed in the
course of the sort:
293
Table of Operations
START |М-1|М-2|М-3 |ЅТАКТ |М = 1 a= M = 1 | FINISH
E»
A(1)129 | 129 129 56
A(2)267 | 267 | 56 "6 129 | 41
A(3) 56 267 | 41 129
A(4) 41 267 A
T2: Bubble Sort with Flag
10 REM "SORTFLAG"
20 PRINT "TYPE NUMBER OF ITEM
S TO BE SORTED"
25 PRINT "MAXIMUM NUMBER 50"
30 INPUT X
35 IF X550 THEN GOTO 25
40 DIM А(50)
60 PRINT "ТҮРЕ NUMBERS ONE АТ
А ТІМЕ"
70 PRINT "UNSORTED LIST"
80 FOR N=1 TO X
90 INPUT Z
100 LET A(N)=Z
110 PRINT A(N) ;" ";
120 NEXT N
125 PRINT
130 REM **SORTING ROUTINE****
140 FOR N-1 TO X-1
145 LET S=0
150 FOR M-1 TO X-N
160 LET C-A(M)
170 LET D=A (M+1)
180 IF C<=D THEN GOTO 210
190 LET A(M)=D
200 LET A(M+1)=C
205 LET S=1l
210 NEXT M
215 IF S=0 THEN GOTO 230
220 NEXT N
225 REM *kkkkkkkpNDřkkkkk
230 PRINT "SORTED LIST"
240 FOR N-1 TO X
250 PRINT A(N);" ";
260 NEXT N
In order to ensure that the sort is completed as quickly as possible, a
flag (in this case the variable S) is introduced to indicate if it has been
necessary to swap elements in the list. S = 1 when a swap has occurred
and sorting wil continue until 5-0 at line 215. This prevents
unnecessary sorting taking place. The procedure and program are
otherwise the same as the bubble sort. The lines 145, 205 and 215 have
been inserted into the ''BUBBLE'' program.
294
Exercise
Draw up the table of operations for this program, as was done for the
“ВОВВІЕ””.
ТЗ: Alphabetic Sort
The Bubble Sort (and all other sorts) may be used to sort strings by
using appropriate string variables and string arrays.
5 REM “ALPHASORT"
10 PRINT "HOW MANY STRINGS"
20 INPUT X
30 PRINT "MAXIMUM 10 CHARACTERS"
35 PRINT
40 DIM А$(Х,10)
50 FOR N-1 TO X
60 INPUT AS(N)
70 NEXT N
80 PRINT "UNSORTED LIST"
90 FOR N-1 TO X
100 PRINT AS(N),
110 NEXT N
120 PRINT
130 НЕМ **SORTING ROUTINE**
140 FOR M=1 TO Х-1
150 FOR N=1 TO X-M
160 IF AS(N+l) >=A$(N) THEN GOTO 209
170 LET Т5-А5(М-1)
180 LET AS(N+1) =A$(N)
190 LET AS(N) -T$
200 NEXT N
210 NEXT M
220 PRINT
230 PRINT "SORTED LIST"
240 FOR N=1 TO X
250 PRINT AS(N),
260 NEXT N
Some care must be exercised if the above sort is to be used on numbers
entered as strings. The example given below shows that it will work
frovided one ensures that all numbers entered have the same number of
figures.
(1 Incorrect use:
HOW MANY STRINGS
MAXIMUM 10 CHARACTERS
UNSORTED LIST
129 99
543 6
456 897
567 21
345 45
295
SORTED LIST
123 21
345 45
456 543
567 6
897 99
(п) Correct use:
HOW MANY STRINGS
MAXIMUM 10 CHARACTERS
UNSORTED LIST
123 099
543 006
456 897
567 021
345 045
SORTED LIST
006 021
045 099
123 345
456 543
567 897
Т4: Insertion Sort
This is another type of sort which is more efficient than the Bubble Sort
and is also the basis of an even faster sort called a Shell Sort. Speed is a
prime consideration when sorting large amounts of data.
Consider the list of numbers:
3 2 5 4 1
We start with the first entry іп the list. Then we take the second item,
compare the two, and swap if necessary. Then the second is compared
with the third, a swap performed if required, and 7f a swap was made
the first and second are compared again, and swapped if necessary.
Then the third item is compared with the fourth, and so on. The list
above will be sorted like this:
296
Swap 3 2
у 4
2 3
i23
3 9
777773
Swap 5 4
у +
4 5
9
Swap 5 1
+ +
1 5
Бе «>
Swap 4 1
у +
1 4
es:
Swap 3 1
+ 4
1 3
— a
Swap 2 1
V 4
1 2
Consider the list A(1), A(2) . . . A(X). To insert item A(I+ 1) in the
correct position:
Let T = A(I+ 1), then
if T> = А(Т) no swap is necessary and no further comparisons аге
required.
if T<A(I) we let A(I + 1) = А(1 and we move on to А(1- 1), then
if T» = A(I- 1),we let A(T) = T and insertion is complete
if T<A(I- 1), we let A(T) = A(I - 1), and so on down the list.
The various steps we will make in the program are therefore as follows:
1) Set J 2 I and T = A(I +1)
2) If T^ = A(J) let A(J + 1) = T and stop
3) Let A(J + 1)= A(QJ)
4) LetJ=J-1
5) If J<1 let A(J + 1) = T and stop. If not, go to (2).
6) Repeat for each value of I (from 1 to N-1) where
N = number in list.
297
300
310
SAO
330
340
280
Program Listing
REM "INSERT"
РЕІМТ "HOW MANY NUMBERS?"
РЕІМТ
РЕІМТ
ІМРІТ X
DIM ñ(X)
PRINT "ТҮРЕ NUMBERS"
FOR N=1 TO X
ІМРМТ ACN)
NEXT N
PRINT
PRINT “UNSORTED LIST"
ЕСЕ N=1 TO X
PRINT AChND;" "3
NEXT N
РЕІМТ
РЕМ FE Ж 3€ 3€ 9€ 3C KKH HHH EH
жж SORTING MODULE жж
FOR I=1 TO X-1
LET J=I
LET TzACI-*1)
IF T >= ACI) THEN GOTO 270
LET AtCJd+1)=A¢.))
LET J=J-14
IF J >= 1 THEN GOTO 220
LET ACJ+1)=T
NEXT I
REM
XxEND SORT MODULE жж
555525555522 22555
РЕІМТ
PRINT “SORTED LIST"
ЕСЕ N=} TŪ X
PRINT ACN)" ";
NEXT N
FEM xENIS x
A trace of the program, using our example list again, can be shown like
this:
298
T5: Shell Sort
The procedure in this sort is to precede an insertion sort by a process
which, if we consider a list of numbers to be placed in ascending order
left to right, will move low values to the left and high values to the right
more quickly.
Consider an 8 element list A(8), holding the values: 74, 32, 59, 46,
26, 9, 62, 42. The sort proceeds in the following stages:
1) Divide the 8 by 2 and compare elements 4 positions apart in the
list, swapping if necessary:
A(1) A (2) A (3) А (4) A(5) А (6) А(7) А (8)
74 32 59 46 26 9 62 42
Сотраге А(1) апа А(5) Swap
A(2) and A(6) Swap
A(3) and A(7) In order - leave
A(4) and A(8) Swap
New list:
26 9 59 42 74 32 62 46
2) Divide the 4 by 2 and compare the elements 2 positions apart in
the list and swap if necessary:
26 59
g me
59 74
42 (SWAP) 32
74 (SWAP) 62
42 32 46
New list:
26 9 59 32 62 42 74 46
3) Divide 2 by 2 and compare elements 1 apart in the list, which is
using the equivalent of an insertion sort to give the final order:
9 26 32 42 46 39 62 74
The steps we make in the program are as follows:
a) Select an integer S (number of positions apart from
comparison). This is usually taken as INT (N/2) where
299
b)
c)
N = number of items in the list.
Sort the lists of items Š positions apart, by comparing and
swapping if necessary.
If S<1 then stop, since the list is sorted.
If S>=1 then pick a new value of S (usually INT(S/2)), and
repeat steps b) to d) as often as necessary.
5 REM "SHELL"
10 PRINT "HOW MANY NUMBERS?"
20 INPUT X
30 DIM A(X)
50 PRINT "TYPE NUMBERS"
60 FOR N-1 TO X
70 INPUT A(N)
80 NEXT N
90 PRINT
100 PRINT "UNSORTED LIST"
110 FOR N-1 TO X
120 PRINT A(N); " ";
130 NEXT N
140 PRINT
198 REM **SORTING ROUTINE**
200 LET S-X
210 LET S=INT (S/2)
220 IF S«1 THEN GOTO 400
230 FOR K-1 TO S
240 FOR I-K TO X-S STEP K
250 LET J-I
260 LET T=A(I+S)
270 IF T»-A(J) THEN GOTO 312
280 LET A(J+S) -A(J)
290 LET J=J-S
300 IF J»-1 THEN GOTO 270
310 LET A(J+S) =T
320 NEXT I
330 NEXT K
340 GOTO 210
350 REM **END OF SORT**
400 PRINT
410 PRINT "SORTED LIST"
420 FOR N-1 TO X
430 PRINT A(N) ;" ";
440 NEXT N
450 REM **END**
300
Hand trace of Shell Sort
Consider the 8 element list 74, 32, 59, 46, 26, 9, 62, 42.
X =8.
310
T = 1 2 3 4 2 4 3
2
9
)=74 A(6)=32 A(8)=46
i
A(1)=26 A(2)=9 A(7)=62 A(4)
62 42 32 46 62 4
At this stage (1) the list is 26, 9, 59, 42, 74, 32, 62, 46.
210
220
230
240
250
260
S | 2 S=1
Қ = 1 2
[= J 2 3 4 5 6 2 4 6
J = 1 2 3 4 5 6 2 4 6
T = 59 42 74 62 46 32 42 46
A(7)=74
A(5)=62 A(8)=46 A(4)=32 A(6)=32 А(8)-46
At this stage (2) the list is 26, 9, 59, 32, 62, 42, 74, 46.
The final stage is the comparison of neighbouring elements using the
insertion sort technique, to which the Shell Sort routine is equivalent
when S = 1. This is perhaps more easily seen if we consider the trace
below of the operation of the Shell Sort program on a simple 5-item list,
in which only two passes need to be made.
301
I = 3 r = 2 I = 2
J = 3 J=2 J = 2 Start
T=A (5) T=A (4) T=A (5) Pass 2
A(2)=4
А(3)-1
А(4)-3
А(5)-5
Тһе two methods of tracing а program illustrated here should show you
the method by which a systematic analysis can be made of the changing
values of variables in a program as processing proceeds. This is a
procedure you should put to use when designing a program (i.e. in
checking that the algorithm will work as intended) and when checking
the operation of other people’s programs that you wish to analyse. The
procedure is also a great help in debugging a program. Break points
inserted into the program (STOP commands), after which you can
print the values of variables by direct commands, or PRINT
statements, inserted as appropriate to print the values of variables at
each step in the program, will enable you to check that the values
occurring in the program are the same as the ones your trace diagram
shows. You can even LPRINT values to get a printout, if many passes
are to be made in the program.
T6: Quick Sort
This provides a fast sorting technique which works by subdividing the
list into two sub-lists and then subdividing the sub-lists. The principle
of the Quick Sort is as follows: consider a list A(X) containing X
numbers. We assume as an example that X = 8 and the numbers are as
shown below. The following steps are carried out:
302
1)
2)
3)
1)
Initialise two pointers, I and J, at opposite ends of the list. Let
X(I) be the reference number. In our example, this is 63.
I J
63 27 43 96 72 31 82 43
Compare the two numbers indicated by the pointers and swap if
necessary.
I J
43 27 43 96 72 31 82 63
Move the pointer opposite the reference number one place
towards it.
| J
43 27 43 96 72 31 82 63
Repeat steps 2) and 3) until I= J.
I J
43 27 43 96 72 31 82 63
! J
45 27 43 96 72 31 82 63
I J
43 27 43 63 72 31 82 96
' J
43 27 43 63 72 31 82 96
I J
43 27 43 31 72 63 82 96
I
43 27 43 31 63 72 82 96
When this stage has been reached the list has been split into two
sub-lists. The reference number is now in its correct position in
the list, and the sub-lists are the numbers to the left and right of
this position.
303
5) One of the lists is stored for future sorting (see below) and the
other is taken through steps 1 to 4 above.
[43 27 43 31] 63 [72 82 96]
mss, ee ee
continue with store
sub-list sub-list
in correct
position
I J
43 27 43 31
I J
31 27 43 43
г J
31 27 43 43
New Sub-list
[31 27 43)
31 Zi 43 in correct
position
31 27
27 31 43
in correct
position
6) This process is repeated, in each case storing a sub-list where
necessary, and finally going back and sorting all stored sub-lists
so that eventually each number is in the correct position.
The left-hand and right-hand numbers of a list are denoted by sub-
scripts L and R respectively.
The pointer positions are denoted by I and J and a flag S is set to
indicate the pointer at the reference number, so that:
S = 1 if reference number at pointer I
S= – 1 if reference number at pointer J
If at the end of step 4 the reference number is at I (as in our example)
then the list has been split into:
reference
sub-list sub-list
Es. uni l= I Пі, ... > X)
The right-hand list is remembered by setting up a stack, using an array
S (P,2) with P initially set to zero. As each sub-list is stored, we make:
P=P+1 S(P,1)2I + landS(P,2)=R
304
The array S is initially dimensioned as S(X,2) for a list with X
elements. P indicates the number of the sub-lists; S(P,1) the left-hand
element and S(P,2) the right-hand element of the sub-list. In the
example given, at step 5 we will have the first sub-list generated stored
by setting:
P = 1, S(P,1) = 6 and S(P,2) = 8
Thus each list to be stored is placed in sequence into the array, this
process being known as PUSHing on to the STACK.
When the sub-list that the program continues with finally has only
one number we must return to sort the stored lists. We retrieve a stored
sub-list (POP a list out of the STACK) by letting:
L=S(P,1),R=S(P,2)andP=P-1
and continuing until all the lists are sorted.
Program Listing
= КЕМ "QUICK"
10 PRINT "HOW MANY NUMBERS?"
20 INFI'T X
20 DIM A(X)
40 DIM 5(Х,2)
SO PRINT :*"INFUT NUMBERS"
во ЕКПЕ N=1 TO X
70 INFUT АСМ)
Z0 NEXT М
90 PRINT
100 PRINT “UNSORTED LIST"
110 FOR N=i TO X
120 FRINT ACN" "3
130 NEXT М
140 PRINT
LEQ REM же Ж ЖЖ ыы 3
+ жж SORTING ROUTINE жж
190 LET P=0
200 LET L=
210 LET R=
Жә LET. Lim
230 LET J=
240 LET $=
2 СІ = ACJ) THEN GOTO =
270 LET ACD =ACN
280 LET ACJ3I=T
290 LET 5з-5
200 IF S=1 THEN LET I=I+1
ӘТО IP Sel THEN LET Ue Jed
320 IF I<J THEN GOTO 250
330 IF Ізі >= R THEN GOTO 270
340 LET F=F +!
350 LET S(P+1)
360 LET 5Р2)
370 LET RzI-1
1
i+
Е
305
280 IF L«R THEN GOTO 220
290 IF Р=0 THEN GOTO 420
400 LET L=icFs1)
410 LET Е->2(Р.2)
420 LET Ғ-Ғ-1
4260 GoTo 290
440 REM w* END OF SORT ++
3C 3c 3C 3€ 3C 3€ 363€ ЖЗ
450 PRINT
4&0 PRINT “SORTED LIST"
470 FOR N-1 TO X
420 PRINT ACNO:" ";
490 NEXT N
200 REM жж ЕМПРЕПС жж
Lines 190 - 230 initialise P, and set values for L, R and the pointers
I and J.
Line 240 sets the flag which indicates the position of the reference
pointer (S = - 1).
Lines 250 — 290 make the interchange of A(I) and A(J) if necessary
and reset the flag.
Lines 300 — 320 move whichever of I and J is to be moved, according
to how the flag is set.
Line 330 checks if I is at the end of the list, bypassing the sub-list
storage routine.
Lines 340 — 360 ‘push’ sub-lists on to the stack.
Lines 370 and 380 check if the sub-list has more than one element,
sending control back to line 220 if it has.
Line 390 sends control to the print routine if no sub-lists are stored.
Lines 400 — 420 ‘pop’ sub-lists out of the stack.
Line 430 starts the sort routine for the ‘popped’ sub-list.
T7: Index Sort
When data records or files contain several items (‘fields’) of
information we often need to sort them according to one particular
item. An index sort routine will enable us to do this.
For example, we may have a series of records each containing a
reference number, name, sex, age, home town and occupation:
10 SMITH MALE 21 OXFORD BUTCHER
20 JONES FEMALE 32 ENFIELD GROCER
Each record contains six fields. We might wish to sort these records
alphabetically by name (field 2) or numerically by age (field 4). A sort
of the type presented here enables this to be done for any of the fields.
Since it uses string arrays to hold records and performs an alphabetical
sort it is necessary for all numerical items in any field to contain the
same number of digits. We must hence use 010, 020, 100, 200 and not
306
10, 20, 100, 200, using leading zeros to maintain the value, but giving
the same number of digits.
The procedure is as follows:
1.
Set up an array N$ (N,L,C) containing N records, each of L
fields with a maximum of C characters in any string. For
example, we might use an array N$ (10,5,20), to represent 10
records, each with 5 fields, which can each contain up to 20
characters.
Decide on the key field (i.e. the field you wish to sort) — say the Jth
field. We must then set up an array K$(N,C) to store it, and let
K$ (R) = N$ (R,]) for the number of records (FOR R = 1 to N)
so that the list K$ (N,C) will then contain the items we wish to
arrange in order.
Sort the key field into ascending order. This is done in the
subroutine starting at line 900 by counting how many times each
element in the array K$ (N,C) is >= the other elements
(including itself). ‘This sort uses a numerical array X(N) to store
the result of this count (P) for each element, by setting X(P) to
equal N, when K$(N) is the item being checked.
We first set P = 1 (since each item is equal to itself) and then
check through the other items of K$ (lines 920 to 970), making
the count by letting P = P + 1 when the element is >= another
element. If the elements are equal, the original order in N$ is
kept (line 960): (i.e. test first element of K$ and set X(P) = 1,
reset P, test second element of K$ and set X(P) = 2, etc.)
For example, with 10, 30, 20, 40 as our K$ list, the array X(4)
would hold the values:
10 X(1)- K$ (1)
30 X(3)= K$ (2)
20 X(2)-KS$ (3)
40 X(4)- К (4)
Printing out K$ (X(1)) to K$ (X(4)) in order will give the sorted
order of K$ elements.
The array N$ (X (N), L, C) will now consist of the records
sorted in the appropriate order, according to the field chosen,
and is printed out using the loop variables R and I to access N$
(X(R), I) in lines 290 to 340.
Program Listing
5 КЕМ "INDEX"
10 PRINT “SORTING RECORDS"
20 FEINT »» "ТҮРЕ MAXIMUM NUMBE
К OF CHARACTERS IN ANY ITEM"
307
30 INFUT C
40 PRINT 33 "HOW MANY RECORDS?"
SO INFUT М
ео PRINT +, “HOW MANY ITEMS IN
EACH RECORD?"
70 PRINT
Өө МЕЛТ L
SE REN 333 3 Хы HH
##INITIALISE $ ARRAYS ++
ЭО DIM ММУ Li; U)
100 DIM K$6N3:0CO
110 DIM ХОМ)
120 REM 3333 5 ЖЕ EERE
ЖЖІМРИТ RECORDS жж
130 FOF Р-і ТОМ
140 PRINT “ТҮРЕ "#15" ITEMS FOR
RECORD "sk
20 FOR Ісі TO L
160 INFUT N$iE:I2
170 NEXT I
120 NEXT F
190 PRINT
200 PRINT "WHICH ITEM IS SORTIN
G KEY?"
210 INPLT J
220 FOR Есі TON
220 LET EKSCRI=NSCRy J)
240 NEXT Е
750 GOSE VOO
260 PRINT
270 FRINT “SORTED RECORDS ARE: "
220 PRINT
290 FOR Е=1 ТОМ
200 FOR Ісі Tü L
310 PRINT N$CXORD IOS" "5
320 NEXT I
220 PRINT
240 NEXT Е
220 PRINT
260 PRINT "DO YOU WISH TO CONTI
ММЕЗСҮ/М9"
97/0 ¿NPUT Үз
280 IF Y$-"Y" THEN GOTO 200
390 STOP
400 REM *##*#FROGRAM END жж
3C 3t 3€ 3€ 3€ € € 3E € 9€ 9E 3€ 9€ C 3E 3E 3€ 3€ 9€ 3C 3€ 903€
ООо REM J39)t3 3 9 3 9€ X 9 9€ 963€ 9€ 9€ 96 3€ 3€ 9E 9E Ж
##S0R TING SUBROUTINE «3
700 FOR Асі TON
S10 LET Pel
720 FOR Е=1 TO N
930 IF K$(ñ3:K$(E) THEN LET FF
940 IF КФА) =КФСЕ) THEN GOTO 96
750 GOTO 970
760 IF АРЕ THEN LET Р=Р+1
970 NEXT E
950 LET ХҰРотА
990 МЕХТ А
308
1000 RETURN
1010 REM ** ENDSUE ++
ЗЕ ЗЕ ЗЕ HEHE ХАЖ
For example, if we input a storage array of £ records with 3 fields,
maximum 6 characters in any item, and use as input data:
SMITH, 460, OXFORD
JONES, 080 LEEDS
BROWN, 730, YORK
WHITE, 095, BATH
Results are as follows:
(1) Using field 1 as key
Sorted records are:
BROWN 730 YORK
JONES 080 LEEDS
SMITH 460 OXFORD
WHITE 095 BATH
(п) Using freld 2 as key
Sorted records are:
JONES 080 ^ LEEDS
WHITE 095 BATH
SMITH 460 OXFORD
BROWN 730 YORK
(ш) Using field 3 as key
Sorted records are:
WHITE 095 BATH
JONES 080 LEEDS
SMITH 460 OXFORD
BROWN 730 YORK
T8: Linear Search
The most straightforward way of looking for a particular number in a
list of unsorted numbers is to examine the list one by one in each case
comparing with the *wanted' number.
In this program a set of random numbers is created between 100 and
199 and it is arranged so that there is only a single occurrence of each
309
number. This is in lines 40-60. The list is printed out in lines
70-110. The search routine is then carried out in lines 200 — 300.
Clearly a number near the beginning of the list is found quickly but one
at the end rather slowly. For a 5@ element list the average number of
searches will be 25.
5 REM "SEARCHI"
10 DIM A(100)
15 PRINT "TYPE NUMBER <100"
20 INPUT N
30 IF N»100 THEN GOTO 15
40 FOR M=] TO N
50 LET A(M)=INT (1ØØ*RND) +100
52 FOR R=1 ТОМ-1
54 IF A(M)=A(R) THEN GOTO 50
56 NEXT R
60 NEXT М
70 PRINT "UNSORTED LIST"
80 FOR M=1 TO N
90 PRINT A(M);" ";
100 NEXT M
110 PRINT
200 REM **LINEAR SEARCH**
210 PRINT "TYPE NUMBER BETWEEN"
220 PRINT "100 AND 199"
230 INPUT X
249 FOR I-1 TO М
250 IF X=A(I) THEN GOTO 300
260 NEXT I
270 PRINT "NUMBER NOT IN LIST"
280 PRINT "AFTER ";N;" SEARCHES"
290 GOTO 400
300 PRINT "NUMBER ";X;" AFTER ";
I;" SEARCHES"
400 REM **END**
T9: Binary Search
This is a much faster search technique than the linear search but can
only be used for a list that has already been put in order. In many
applications you will be dealing with an ordered list and under such
circumstances this is the appropriate method to use.
In the program the binary search technique is in lines 500 to 600.
The basic idea is to compare the wanted number with the middle item
of the ordered list. The wanted item is then either smaller (in which
case we know it is in the first half of the list) or larger (in which case it is
in the second half of the list) than the middle item, unless it is equal to
it-in which case we have completed our search. The process is
repeated, in each case halving the list. Consider a search for 30 in the
following list:
l 2 4 6 8 10 12 14 16 18 20 24 28 30 36
We first choose 14 (middle).
310
Our list is now:
16 18 20 24 28 30 56
and we choose 24 (middle).
Our list 1s now:
28 30 36
We select 30 (middle).
Thus we have found the number in three searches (compared with
fourteen using the linear search).
In the program the following sections occur:
(1) Setting up initial unordered list and printing out (lines
10 — 150).
(ii) Sorting this list into order and printing it out (lines 200 — 330).
(ш) Binary search with printout (lines 500 — 680).
5 REM "SEARCH2"
10 DIM А(50)
20 PRINT "TYPE NUMBER <50"
30 INPUT N
40 IF М>50 THEN GOTO 20
50 FOR M-1 TO N
60 LET A(M)=INT (100*RND)+100
70 FOR R=1l TO M-1
80 IF A(M)-A(R) THEN GOTO 60
99 NEXT R
100 NEXT M
110 PRINT "UNSORTED LIST"
120 FOR M-1 ТОМ
130 PRINT A(M);" ";
140 NEXT M
150 PRINT
200 REM **{NSERTION SORT**
210 FOR Ізі ТО N-1
220 LET J-I
230 LET T=A(I+1)
240 IF T»-A(J) THEN GOTO 280
250 LET A(J+1)=A(J)
260 LET J=J-1
270 LET J»-1 THEN GOTO 240
280 LET A(J+1)=T
290 NEXT I
295 REM ***ENDSORT***
300 PRINT "SORTED LIST"
310 FOR M-1 TO N
320 PRINT A(M);" ";
330 NEXT M
340 PRINT
350 PRINT "TYPE NUMBER REQUIRED"
360 PRINT "BETWEEN 100 AND 199"
370 PRINT "TO FINISH TYPE 999"
380 INPUT X
390 IF X-999 THEN GOTO 709
400 PRINT
311
Results:
410
500
510
520
530
540
550
560
570
580
590
600
610
620
630
640
650
660
670
680
690
700
PRINT "SEARCH ";N;" ITEM LI
ST"
REM **BINARY SEARCH**
LET L=l
LET H=N
LET С-О
LET M=INT ((H+L) /2)
LET С=С+1
IF X=A(M) THEN GOTO 630
IF L>=H THEN GOTO 660
IF X>A(M) THEN GOTO 610
LET Н-М-1
GOTO 540
LET L=M+1
GOTO 540
PRINT "NUMBER FOUND ";X
PRINT "AFTER ";C;" SEARCHES"
GOTO 350
PRINT "NUMBER NOT FOUND"
PRINT "AFTER ";C;" SEARCHES"
GOTO 350
REM **END SEARCH**
REM **END**
TYPE NUMBER «50
UNSORTED LIST
117 118 101 189
188 197 172 106
130 181 100 165
155 167 199 138
113 143 154 194
106 107 111 113
128 130 131 133
148 150 Loo 154
165 167 168 172
144 128
150 107
168 160
186 190
131 142
SORTED LIST
100 101
119 122
143 144
160 163
186 188
189 190 194 197
TYPE NUMBER REQUIRED
BETWEEN 100 AND 199
LO FINISH ТҮРЕ 999
SEARCH 40 ITEM LIST
NUMBER FOUND 198
AFTER 5 SEARCHES
T10: Storing a List
We can store data in an array for use in a program via INPUT loops
when there is more data to be inserted than we care to put directly in
the program using LET instructions. There are programs in the text
that use this technique (e.g. “ЕГЕМЕМТ”). To illustrate the
214
111
127
175
122
119
117
138
155
175
198
198
148
133
163
153
118
142
157
181
199
technique, here is a simple example that doesn't require you to INPU T
anything. Key in and run the first program to create A(N) and fill it
with random numbers. Edit the program, replacing the original lines
with those of the second program. SAVE this program. LOAD it back
in. If we used RUN it would clear all the variables, and wipe out the
array we have stored.
Program execution must be started with a GOTO statement, in this
case GOTO 10. The array will then print out.
10 DIM A(40)
20 FOR N=1 TO 40
30 LET A(N)=INT (100*RND)+100
40 NEXT М
10 REM "SAVED*ARRAY"
20 REM **EXECUTE PROGRAM**
30 REM **USING GOTO 10%%
40 PRINT "LIST OF RANDOM NUMBERS"
50 PRINT "BETWEEN 100 AND 199"
60 FOR N-1 TO 40
70 PRINT A(N)
80 NEXT N
So this 1s the general procedure:
(1) Write an array creation program and run it, i.e. A(N) created
and data inserted.
(2) Edit out lines and put in additional lines as required.
(3) SAVE the final program.
(4) LOAD program and execute using a GOTO statement.
To avoid the possibility of the user entering RUN, we can use a
structure which automatically initiates the program on loading. The
program below for the ZX81 also illustrates the fact that one may use a
string variable as a program name.
Lines 10 to 80 create array and have the input routine. These lines
could be edited out as soon as the data was input, or left in to enable
(through the use of RUN) a different set of data to be input.
Line 90 onwards are the program to use the stored data.
Line 9010 requests a string input to be used as the program name.
9020 gets the string, and 9030 and 9040 give you the chance to write it
down before you forget.
9050 waits for a key to be pressed, and 9070 saves the program and
its variables. One of these variables stores the line the computer had
got to in the program, and when loaded back it starts where it left off
(9070) and goes to line 90 automatically.
10 REM **AUTO-RUN ROUTINE**
20 REM AUTOMATIC RUN WILL
PRESERVE VARIABLES
30 REM AVOID STATEMENTS
OR EDIT THEM OUT.
40 REM ***DIMENSION/INPUT, ТО
STORE VARIABLES ***
50 DIM А(20)
60 FOR F-1 TO 20
313
70 INPUT А (Е)
80 NEXT F
90 PRINT "PROGRAM TO USE DATA"
100 FOR F=20 ТО 1 STEP -1
110 PRINT A(F)
120 NEXT F
130 REM ...... MORE PROGRAM
140 REM .......
8990 REM **SAVE AND AUTO-RUN**
9000 CLS
9010 PRINT "INPUT PROGRAM NAME"
9020 INPUT AS
9030 PRINT "PROGRAM NAME:";A$
9949 PRINT "READY TO SAVE.NOTE P
ROGRAM NAME.PRESS A KEY TO
SAVE PROGRAM","AFTER SETTI
NG CASSETTE TO RECORD*****"
9050 IF INKEYS="" THEN GOTO 9050
9060 CLS
9070 SAVE AŠ
9075 REM **GOTO LINE AFTER DIM/
INPUT ROUTINE IF NOT EDITED
OUT kk
9080 GOTO 90
The Spectrum has an automatic message and built in wait-for-key-
press routine. It also has an automatic run-after-LOAD facility. If a
line is entered in a program of the form:
9000 SAVE ‘‘program’’ LINE 200
and the program is saved with a GOTO 9000, the program will start
running after loading by going to the line stated (200 in the example).
For the Spectrum, this program needs modifying by deleting lines
9070, 9075, 9080, changing 9040 to read PRINT*'NOTE
PROGRAM МАМЕ”, 9050 to PAUSE 0, and 9060 to SAVE
A$ LINE 90.
T11: Storing a String Array
The ZX81 program PRETTY draws a picture on the screen (slowly!)
which is stored in the array A$, dimensioned in line 100. If this
program is run the array A$ is created, and the screen display stored,
character cell by character cell, in A$. The lines in the program can be
edited out so that finally we have a program like PRETTY2. This may
be SAVEd and includes the created array A$. To execute the program
PRETTY2 after loading we must use GOTO 5, to avoid the use of
RUN, which clears all arrays (and hence A$) before execution starts.
5 REM "PRETTY"
10 FOR J-1 TO 19
20 FOR N=ø TO J*12
30 PLOT 32-27%2%5ІМ (N/(J*6)*PI),
224J*COS (N/(J*6)*PI)
40 NEXT М
50 NEXT J
314
100 DIM A$(704)
110 FOR I=0 TO 21
120 FOR Ј=1 TO 32
130 LET A$(J+32*I)=CHR$ PEEK (PEEK
163964256*PEEK 16397-4J-433*I)
140 NEXT J
150 NEXT I
5 REM "PRETTY2"
10 PRINT A$
Notice that we have stored the screen display in the array.
Check you understand the process of PEEKing the display file.
The Spectrum stores a screen display using a special form of SAVE.
This has the form: SAVE “РКЕТТҮ” SCREENS, where PRETTY
can be any name. This is loaded back using LOAD “РКЕТТҮ”
SCREENS.
Try this procedure on your Spectrum. The program above can be
revised for the Spectrum. Enter just the following lines:
10 FOR J=1 TO 40 STEP 4
20 FOR N - 0 TO J*12 STEP 4
30 PLOT 125 + J*2*SIN(N/(J*6)* PD,88 + J'COS(N/(J*6)*PI)
40 NEXT N
50 NEXT J
Use SCREENS to save the picture as above. To continue with screen
displays, the Spectrum can store a screenful of characters in much the
same way as the ZX81 program above, using SCREENS to access each
character in turn, placing them in sequence in array A$(704). A
screenful of characters is generated at random, using the single
characters from the Spectrum character set, placing these along each
line.
The double loop (lines 60 to 100) uses SCREENS (F,N) to check
each character along each line, placing it in the array A$.
= DIM 4$(7042
10 FOR F=0 TO 21
20 FOR NzO TO 31
30 PRINT АТ F:N? CHES (32+ ЕМІ
#97)
40 NEXT N
SO NEXT F
ео FOR Ғ-о Tü 21
70 FOR М-о ТО 31
SO (ЕТ AS(N+14+32#F3=SCREENS
СЕ» №
70 NEXT N
100 NEXT F
Now edit out all the lines, replacing 5 with 5 PRINT A$, and RUN the
program using GOTO 5.
315
The same program for the ZX81 needs to use PEEK to access the
display file, just as in “РКЕТТҮ”. Replace lines 5 to 50 in
“PRETTY” with the following, to print a random set of ZX81
characters on the screen:
5 КЕМ "SCREENFULL "
10 FOR F=1 TO 704
20 PRINT СНЕФ INT ( REND #54);
30 NEXT F
The same principle holds good for any string array or numeric array.
Once the program has been run and the data inserted into the array,
the data is safe as long as RUN is not used again, and can be accessed
as required. The ELEMENT program treated in Unit W3 uses this
procedure to store data required in the program.
Exercise
Write the appropriate array creation program for the following
program:
10 REM "SAVEI10"
20 REM **THIS PROGRAM MUST BE**
30 REM **EXECUTED USING GOTO10**
40 PRINT “MONTHS OF THE YEAR"
50 FOR N-1 TO 12
60 PRINT M$ (N)
70 NEXT N
T12: Storing Data in Strings
Strings can be used to store data, which may be accessed using the
string-handling instructions. The data can also be re-assigned, or new
values inserted. Numbers may be used, the STR$ and VAL
instructions enabling conversion from numbers to strings and vice
versa.
The first example has the data stored in A$. The names of the
months are all three letters long, and can thus be accessed using the
simple numeric calculation of line 70.
10 REM STRING DATA STORE
20 REM *AS HAS DATA*
30 LET A$="JANFEBMARAPRMAYJUNJ
ULAUGSEPOCTNOVDEC"
40 REM *DATA INPUT*
50 PRINT "INPUT MONTH(1 TO 12)
н
60 INPUT MONTH
70 PRINT "MONTH ";MONTH;" IS "
;AS(MONTH*3-2 TO MONTH*3)
316
The next program has the full names of the months, with varying
lengths. Full stops are used to make the principle clear, but spaces
between the months would be used in a practical program. (As it is, a
full stop is printed after the month, rather than the useful space.) The
program stops the search after the required month has been found (line
100), but is a little slow on the ZX81 unless FAST is used (line 65).
10 REM STRING DATA STORE
20 REM *AS HAS DATA*
25 REM **USE SPACES,NOT FULL S
TOPS IN REAL PROGRAM**
30 LET AS=".JANUARY. FEBRUARY.M
ARCH. APRIL.MAY.JUNE. JULY. AU
GUST. SEPTEMBER. OCTOBER. NOVE
MBER. DECEMBER,"
40 REM *DATA INPUT*
50 PRINT "INPUT MONTH(1 TO 12)
"
60 INPUT MONTH
65 FAST
70 LET P=0
80 LET A-1
90 IF AS(A)="," THEN LET Р=Р+1
100 IF P=MONTH+1 THEN GOTO 140
110 IF P=MONTH THEN PRINT AS (А+
1);
150 PRINT "IS THE MONTH INPUT"
Spectrum users should, of course, delete the FAST and SLOW
instructions, lines 65 and 140.
The next program uses a string to store numeric data. The numbers
are input, and placed in the string as the STR$ string plus ‘‘*’’, which
is used as an indicator. The data is retrieved by using the subroutine
(at line 1000) to step through each number string in turn, returning the
number string as Z$ when RETURN is executed on an asterisk being
found (line 1020). The two data access routines (lines 110 to 140 and
150 to 180) after the initialisation of NSTRING could occur anwhere
in the program. The data can be accessed in an order by suitable
manipulation of the access instructions (e.g. the reverse loop in lines
150 and 180), and NSTRING can be re-initialised as zero at any point.
Counting loops could be used to access an Nth item of data.
Spectrum users should note that the Spectrum has READ and
DATA functions (which are dealt with in Section W), that provide a
more convenient way of storing and retrieving data for many
applications, but are less flexible than string storage in some cases,
especially when used as illustrated below. DATA items must be keyed
in within the program listing and cannot be input.
5 REM *INITIALISE*
10 DIM A(10)
20 LET А5-""
317
REM *DATA INTO STRING*
FOR Е-1 TO 10
INPUT NUMBER
LET А$=А$+5ТА$ NUMBER+"*"
NEXT F
REM .......
REM .......
REM .......
REM *RESTORE START*
LET NSTRING=0
FOR Е-1 TO 5
GOSUB 1000
LET A(F)=VAL ZŠ
NEXT F
FOR F=10 ТО 6 STEP -1
GOSUB 1000
LET A(F)=VAL Z$
NEXT F
РРР
MEN жола»
ЅТОР
REM ***READ STRING SUB***
LET Z$-""
LET NSTRING=NSTRING+1
IF AS(NSTRING)="*" THEN RET
URN
LET Z$2Z$4A$ (NS TRING)
GOTO 1010
318
SECTION U: THE COMPUTER MEMORY
U1: Memory Organisation
Digital computers operate with sequences of numbers in the binary
number system. Binary numbers are numbers to base 2, and our
‘normal’ number system is decimal (base 10).
The BINARY system uses only two digits, 0 and 1. These are
binary digits (bits). The computer holds a bit as a voltage level
( + 5v or Ov) іп a switched pathway.
In the decimal system, a number, for example 418, is coded as a number
using the digits @ to 9. The coding is based on powers of ten. 418
means: (4 times 10 to the power 2) +(1 times ten to the power 1) + (8
times ten to the power 0).
(4x 10” + (1x10) + (8х 10’)
400 + 10 + 8 = 418
The binary system of coding uses powers of two in exactly the same
way.
The number 13 is represented as:
(1x 2") + (1x27). € (0x2) + (1x2?
1 1 0 1 Binary number 1101
8 + 4 + 0 + 1-13 Decimal equivalent
The binary number 101110 is evaluated as:
(1 x 27) + (0 x 2) + (1x 2°) + (1 x 2”) + (1 x 2)) + (0 x 2^)
32 + 0 2,2%. Ü
+ 8 + 4 + = 46 in decimal
Key in the following program, which converts decimal numbers to
their binary representation:
1 REM *DECBI*
2 REM CONVERTS DECIMAL TO
BINARY NUMBERS
10 PRINT “ENTER DECIMAL NUMBER
20 INPUT N
30 PRINT М;
40 LET BS=""
50 LET L=INT (N/2)
60 LET BzN-2*L
70 IF B=1 THEN LET А5-"1"
80 IF B=@0 THEN LET AS="9"
90 LET BS=AS+BS
100 LET N=L
110 IF L>@ THEN GOTO 50
120 PRINT " IS ";В5;" IN BINARY"
Input sequences of numbers to familiarise yourself with the binary
system. The program only deals with positive whole numbers. Trace
319
the progam to see how it works, using the examples 13 and 46 given
above as inputs. Non-integer numbers are dealt with by using an
exponent, as with the E notation system for decimals. Binary numbers
have a binary point, and bits to the left of the point are binary fractions,
representing the reciprocal power of two. The binary number 1.101,
for instance, represents:
GN FEM pe
(1x2) + (91) +( 9) + (93)
1 + 5 + 0 + .125 -1.625
You may have noticed that binary numbers as seen above are all
positive. Negative numbers are dealt with by using a particular form of
binary representation. The method by which the ZX81 and Spectrum
store numbers is described later in this Section.
In a computer, numbers are held in fixed numbers of bits. These are
referred to as words.
A BYTE is a sequence of 8 bits. The sequence of 8 bits
represents a number between 0 and 255 decimal, 00000000
and 11111111 binary. The ZX81 and Spectrum use 8 bit
words, i.e. 1 byte.
Memory in computers is organised as a linear sequence of addresses.
Each address is a memory location or memory cell holding a single
byte. The binary numbers in these locations are interpreted as
numbers, characters or instructions depending on their context in the
computer memory. The organisation of the memory is constant, but
the space occupied by each area of memory varies according to the
program and its requirements. As an obvious example, a long program
takes up more space for storage than a short one.
Memory is of two types:
READ ONLY MEMORY (ROM) is fixed and cannot be
altered. It contains the BASIC interpreter program, and is
built-in to the computer in manufacture.
RANDOM ACCESS MEMORY (RAM) is variable, multi-
purpose memory that holds the current program and all the
other elements of data required to run the program.
Data can only be extracted from ROM (‘read’), and is permanent.
RAM memory can be both read from and written to. Inserting a value
into a memory location in RAM (writing or storing) will wipe out or
overwrite the existing data at that address.
Memory capacity is referred to as the number of Kilobytes (k)
involved. Kilo refers to one thousand, but this is only approximately
true, since a kilobyte is actually 1024 (2”) bytes. The ZX81 has 8k of
ROM memory and, with the memory expansion, 16k of RAM. The
320
Spectrum has 16k of ROM and either 16 or 48k of RAM. The memory
is organised as shown in the diagrams below (called memory maps).
The ZX81 and Spectrum have somewhat different memory
organisations. We will deal first with the ZX81, and then the
Spectrum. Spectrum users should read through the ZX81 section,
however, as definitions of the functions of various types of memory are
covered in this Unit.
ZX81 MEMORY МАР
Address Contents
32767
GOSUB STACK
Unused addresses. No memory
16509
16384
space exists for this area.
8192
ROM memory area. BASIC
interpreter and operating
system program.
0000
Тһе top of memory (КАМТОР) is usually вес ав shown оп switch-on,
at 32767. The computer can be instructed to set RAMTOP at some
lower value, to leave spare memory locations which can be used to
store machine code programs, which are called (like subroutines) from
the BASIC program with the USR instruction. Machine-code
programming is outside the scope of this text.
Some areas of memory are organised in the form of a stack. This is a
system such that the last item entered will be the first to be pulled off
321
the stack. A number may only be placed on the top of the stack of
existing numbers, and the only accessible number 15 the one on the top.
This creates an ordered sequence. In the GOSUB stack this is used to
ensure that the RETURN instructions are followed in correct
sequence. Each GOSUB instruction causes the following line number
to be added to the stack. RETURN then takes the first line number off
the stack to get the correct line number to pass control of the program
back.
The machine-stack memory area is used to keep track of the
operation of the program. The spare memory area is that portion of the
allocated area not occupied by the program and other memory areas.
Although we referred to the top of the stack, it is more correctly the free
end of the stack on to which the numbers are placed. The free end of
the machine stack is at the bottom, in terms of the memory address
sequence, hence the spare memory is below the machine stack in our
diagram.
The calculator stack is used for arithmetic operations. The work
space holds the program line being input and provides temporary
storage for data being manipulated ~ a scratch pad.
The variables area stores all variables initialised in the course of a
program. They are held in various forms, and we shall deal with the
way numbers and variables are stored in the next Unit.
The display file has been covered in Section O. The program area
contains the program lines. This area always starts at address 16509.
All other memory areas ride on top of the program area, moving up or
down as the program lengthens (has program lines added or inserted)
or shortens (has lines deleted), apart from the GOSUB and machine
stacks, which are always at the top of memory.
The systems variables area holds the special variables which store
information concerning the state of the computer for use by the
operating system. Certain of the system variables were introduced in
Section Q. Like the D-FILE system variable introduced there, some of
these variables hold the addresses of the divisions between the areas of
memory. Other variables hold values of addresses, line numbers,
characters, etc., to keep track of what state of affairs is current in the
operating system. You have seen, for instance, that the DF-SZ variable
stores the number of lines on the lower part of the screen. Some other
system variables are dealt with in the next Unit. There are a fixed
number of system variables, and their values are always held at known
addresses between 16384 and 16508. The names of the system
variables are not recognised as BASIC variable names, but are just
mnemonics for the system variable function.
On the ZX81 there is no memory corresponding to addresses
8193-16383. Addresses 0 to 8192 contain the system software in ROM
which holds the BASIC interpreter and operation program in machine
code.
322
SPECTRUM MEMORY MAP
Address Contents
32767 (16k)
USER DEFINED GRAPHICS
65535 (48k)
ROM AREA. BASIC INTERPRETER
RAMTOP
RAM
23734
23552
23296
22528
16381
AND OPERATING SYSTEM PROGRAM
0000
The memory тар of the Spectrum memory is somewhat different from
that of the ZX81. The Spectrum also comes in two versions, one with
16k of RAM, one with 48k. The ROM is also larger on the Spectrum,
occupying 16k. Thus the first 16k of memory addresses (0000 to 16383)
are occupied by ROM on the Spectrum. A 16k version then has the
next 16k of memory as RAM, up to address 32767. The 48k Spectrum
uses addresses 32768 to 65535 for the additional RAM memory. Apart
from the size of memory, the arrangement of memory is the same in
both Spectrum versions, as shown on the diagram. The fixed memory
points are given as the memory address.
The Spectrum memory requires more separate areas (reserved for
the additional functions of the Spectrum), and the organisation is
somewhat different. Working from the top of memory down, we notice
an area set aside for user-defined graphics. This occupies 168 bytes,
323
and is set at the actual top of the memory, which is referred to as
Physical RAM TOP. The bottom of the user-defined graphics area is
the RAMTOP that the computer recognises as the top of memory.
This leaves the user-defined graphics area protected from any
interference by the operating system. On switch-on, the address of
RAMTOP is thus set at 65367 with a 48k Spectrum, 32599 on a 16k
version. This is the memory address of the last existing byte of memory
before the user-defined graphics area. Below this are the GOSUB stack
and the machine stack, with the area of free memory below this, as on
the ZX81.
The calculator stack, work space for lines being keyed in or data
being processed, and the variables storage area are all in the sequence
followed by the ZX81 memory. Then we have a significant difference
between the two memories. The display file on the Spectrum 15 fixed,
and does not appear above the program area, but at the bottom of
RAM. Between the program area and the display file are Spectrum-
specific areas, concerned with input and output and colour. The
channel information area has information required for the operation of
the printer, the keyboard, and the ТУ screen in terms of its division
into top and bottom screens, the bottom one expanding if necessary to
contain the required lines. This area is adjacent to an area of memory
that will be used to store data necessary for the operation of the Sinclair
microdrive disc system when it becomes available and is attached to a
Spectrum. This area ‘vanishes’ without the microdrive and there is no
sequence of memory bytes allocated to it. This area begins at address
23734. Without the microdrive, this address becomes the start of the
channel information area.
System variables occupy 182 bytes of memory, from 23552 to 23733
inclusive. The printer buffer on the Spectrum is larger than that on the
ZX81 because of the need to store information about each of the 8*8
points in a character cell (where the ZX81 only needed to store
character codes). The buffer, to store a full line for the printer, needs
256 bytes. This is because each line of points іп а 32 character line
needs 8*32 bits, and there are 8 of these lines needed to make up a line
on the printer. This buffer occupies the bytes from 23296 to 23551
inclusive.
The colour attributes (see Section W for this) occupy one byte per
character cell, so the storage is 24*32 bytes from 22528 to 23295. These
store the information about the colour (background and printing
colour), brightness and flashing characteristics of each PRINT
position. This information, together with the display file, determines
the screen display. The display file holds the information about the
pattern of dots to be placed on the screen, and the attributes file the
additional data for a colour display. The display file occupies the
memory addresses from the start of RAM (16384) to 22527. This is
6144 bytes, so we can note that on a 16k Spectrum some 42% of RAM
is needed for the display and attributes files only. This leaves about 9k
324
for program and operating areas, and illustrates the fact that high-
resolution graphics take up large amounts of memory.
Below 16384, the memory addresses are all ROM memory. The
more complex operating system of the Spectrum demands more
Instructions in ROM than are required by the ZX81. There is no gap
in memory at all on the 48k machine, all 64k of memory that the Z80 A
chip (the central processing unit) can address being used. On the 16k
Spectrum, of course, the memory addresses above 32767 are unused.
U2: PEEK and POKE
The PEEK and POKE instructions have been introduced for specific
purposes in connection with the display file and character storage. This
should have given you some understanding of their uses. Now that you
have been introduced more generally to the way memory is stored in a
computer, you will notice that these instructions provide direct access
to the memory of the computer.
PEEK N returns the value (in decimal notation) of the
number stored in binary form in the memory byte of address
N. In the ZX81, N must be in the range @ to 8192 to return
the contents of ROM memory, and in the range 16384 to
32767 to return the contents of RAM. For the Spectrum,
ROM extends from @ to 16383, RAM from 16384 to 32767
(16k version) or 65535 (48k version).
POKE M,N places into the memory address M the binary
form of the decimal number N. N must be in the range @ to
255 (to fit in a single byte). For the ZX81, and 16k Spectrum
M must be in the range 16384 to 32767. The 48k Spectrum
uses addresses up to 65535. ROM may not have values
POKEd into it.
In general, we use PEEK to extract from memory any values useful to
our program, and POKE to insert values into memory. Remember
that the values (entered and returned in decimal notation) can be
numbers, characters or instructions. Machine-code programming is
performed by POKEing into a specified sequence of addresses the
values which correspond to instructions which the 780 central
processor chip understands. This sequence of instructions is then called
from within a BASIC program, in a similar fashion to calling a
subroutine, and is executed. At the end of the machine-code program,
a return instruction passes back control to the BASIC program.
We will use PEEK to investigate how numbers and program lines
are stored in the ZX81 and Spectrum. Different types of number have
different formats in which they are held. The normal number in
325
memory is held іп 5-5yte floating роті binary form. Each number is stored
in 5 bytes of memory.
The (те numbers in a program are stored in 2 bytes of memory.
Numbers in a program listing are stored as their printed characters,
then in 5-byte form.
Enter the program below if you are using a ZX81. It PEEKs the
memory locations from address 16509 onwards, 1.e. each address in
memory from the start of the program listing, after printing out the
numbers as instructed in the first three lines, and prints the address,
contents of the address as a decimal number, and the character string
corresponding. The corresponding program and output for the
Spectrum is given after the ZX81 has been dealt with, since the
character codes are different.
5 REM "PROGLIST"
10 PRINT 23
20 PRINT 123E8
30 PRINT 123E-8
40 LET A=16509
50 PRINT A;TAB 10;РЕЕК A;TAB 1
5;CHR$ (PEEK A)
60 LET A=A+1
70 GOTO 50
You will get a display (use COPY to get a printer listing, and CONT to
continue) that looks like this:
23
19300000000
1.23E-65
165809 e
16510 ла =
16511 ла ж
16512 e
16513 245 PRINT
16514 зе 2
16515 93. 5
16516 126 7
16517 153 Е
15518 56 5
16519 а
15520 ә
15521
15522 1:5 *
16523
16524 го -
16525 13 E
16526
16527 245 PRINT
16528 29 1
16529 3@ 2
16530 зі З
16531 42 Е
16532 зе 8
16533 126 2?
16534 ie2 B
16535 55 R
16536 72 7
16537 198 LE?
16538 192 "
16539 118 7
16540
16541 зе 2
16542 14
16543
16544 245 PRINT
16545 29 1
16546 за 2
16547 gi 2
16548 42 E
18549 22 -
16558 зе в
16551 126 ?
16552 199 7
16553 27 9
15554 22 =
163553 122 =
16556 le? Ф
15557 118 Y
16558 e
16559 406 с
16562 15 =
16561
16562 241 LET
16563 A
16564 20 =
163565 29 1
165656 3d &
1655? 33 5
i6568 2o e
155692 з” 9
Notice first the way the ZX81 changes the format of the numbers. 23
prints as 23, but 123E8 is printed as 12300000000, and 123E-8 as
1.23E-6. The operating routines put each number into a standard
format for printing to the screen. In order to present a listing of the
program, which is what you’ve typed in, the computer must hold two
forms of the number; first the literal characters and second the 5-byte
floating point form.
Inspect the printout from the program. The first address printed is
16509, holding zero. This is the first of the two bytes holding the line
number. Notice that the more significant byte comes first. This is the other
way round from normal 2-byte values (those of the system variables,
for example). Since the line number is less than 255, the first byte holds
zero and the second (16510) holds 10.
16511 holds 10 again. This is the number of characters in the line.
16512 has zero, since these two bytes hold the line number as (First
byte value) + 256* (Second byte value), in the standard way.
16513 holds the value 245, representing the keyword character
PRINT. Then come the characters 2 and 3 (codes 30 and 31). Bytes
16516 to 16521 hold the values 126, which indicates that the next
sequence of bytes holds a number, and then 133,56,0,0,0. This is the
5-byte form of 23. We shall see in the next Unit the mechanics of this
way of representing numbers.
Check through the rest of the listing and make sure that you
understand how and why the memory addresses contain the values
they do.
SPECTRUM PROGRAM LISTINGS
The program below for the Spectrum has a different form from that for
the ZX81. This is a consequence of the strange results of the control
characters in the Spectrum character set if used as a CHR$ (see Unit
P2). We must avoid using a PRINT CHR$ instruction for these
control characters. The program sets a logical condition to test the
value of A in lines 60 and 70 which prints “CONTROL CHR”
instead of the CHR$ form if the printing of the CHR$ would cause
problems.
10 PRINT 23
20 PRINT 123E8
30 PRINT 123E-8
327
40 LET A=(PEEK 23635+256*PEEK
23636)
50 PRINT A;TAB 10;PEEK A;TAB 1
5;
6@ IF РЕЕК A>23 OR PEEK A<15 T
HEN PRINT CHR$ (PEEK A)
70 IF PEEK А<-23 AND PEEK A>=1
6 THEN PRINT “CONTROL CHR"
80 LET A=A+1
90 GO TO 50
The results will be as follows. (Use scroll to see the full listing. To get a
printout like the one here, you must BREAK the program when
“Scroll?” appears, then use COPY, then CONT to get the next
screenful.)
1.2ЗЕ +19
1.23E-6
23755 e ?
23756 10 >
23757 10 ?
23758 ә ?
23759 245 PRINT
237862 Ea 2
23751 51 3
23762 14 >
BATES © s
23764. e ?
257855 23 CONTROL CHR
23756 e >
23767 e т
23768 13
23752 e ?
23770 го CONTROL CHR
25771 13
patya © “y
23773 245 PRINT
2377 49 1
23775 sa 2
23776 51 3
597727 вә Е
23778 56 а
23779 14 ?
23780 162 5
23781 =s ?
23782 72 H
23783 198 AND
23784. 192 USR
23785 13
23786 ә т
237857 зә Е:
53788 14. %
23789 © ?
23720 245 PRINT
23791 49 1
23792 sa 2
53793 51 5
23794 БӘ Е
23795 45 m
23796 56 a
23797 14. ?
23798 189 ш
23799 3 =
235800 22 CONTROL CHR
23801 122 >
23802 за? К
238903 13
The PEEKs in line 40 set A to the value of the first memory address of
the program storage area. (See the description of the System Variables
in the next Unit.) Unlike the ZX81 the Spectrum program area moves
around in memory.
After printing the numbers, in a revised notation, setting the
exponent values to have the decimal point after the first digit (a task
328
automatically done by the operating system) the program prints the
first address (23755), which is the first byte of the program area. It then
prints the value stored in this byte, followed by the character code (if
it’s not a control character). Codes not corresponding to a character
with a printed form produce a question mark.
The first two bytes hold 0 and 10. This is the line number, stored,
unlike all other two-byte numbers, with the more significant byte first.
The next two bytes hold the number of characters in the line, stored in
normal fashion, with the least significant byte first. We then have code
245, which is the keyword PRINT, the first instruction in the line. This
is followed by the characters 2 and 3, for printing in the program listing.
This is followed by code 14, which is a control code indicating that the
next 5 bytes are to be interpreted as a number. There are then five
bytes storing the number 23, in the special form in which the Spectrum
handles integers. We will deal with this in the next Unit. Notice that
the code 14 defines for the Spectrum the way in which a character or
number (stored in the same binary form in a memory byte) is to be
interpreted.
After the five bytes of the number comes the ENTER character (13),
signifying the end of the program line. Addresses 23772 and 23773 hold
the next line number, then comes the number of character bytes in the
line, and so on. Note that the number 123E8, which was input in this
form, is stored as this sequence of characters, even though it prints in a
different form, due to the operating system using the five-byte form to
decide what number is to be printed.
Trace the program further than the third line we have included in
the printout, and ensure you can follow the program line arrangement,
as we will refer to this in connection with a program to renumber
program lines automatically later in the text. Although the Spectrum
and ZX81 character codes are different, the program line arrangement
is the same.
Because we know that the address at which a program listing starts
can be found, and the format of the program listing in memory, we can
use PEEK to extract data from a program line. This can be useful to
store data. Enter and run the program below. You should be able to see
how it works. Remember that the first character after the line number
(two bytes) and the line length (two bytes) will be the REM statement.
The characters to be PEEKed will follow this. 5 bytes therefore need to
be added to the start address of the program area.
The Spectrum user needs to use the PEEK expression to find the
start of the program (the address given by M):
40 REM RIALCNIS
20 LET M= PEEK 23635+256# PEEK
22636
30 PRINT АТ 10310
40 FOR F=7 TO 0 STEF -1
S50 PRINT СНЕ% PEEK СМ+5+Р);
&O NEXT F
329
On the ZX81, the start of the program area is fixed. 5 can be added to
this to give the address of the first byte of memory we are interested in
(16509 + 5 = 16514).
10 REM RIALCNIS
20 PRINT AT 10,10;
30 FOR F=7 TO @ STEP -1
40 PRINT CHRS PEEK (16514+F);
50 NEXT F
The reverse procedure is also possible, using POKE. Try this
program.
ZX81:
18 REM ABCDEFG
20 FOR F=0 TO 6
30 POKE (16514+F) , 29+F
40 NEXT F
Spectrum:
10 REM ABCDEFG
20 LET М-РЕЕК 23635+256*PEEK 23636
30 POR F=0 TO 6
40 POKE (M+5+F) ,48+F
50 NEXT F
Тһе Spectrum program again uses а РЕЕК to find the program area
start address, and the different character codes require different values
added to F to give the same result.
Run the program, then LIST it and see what has happened to the
REM statement. If you want an illustration of the care needed when
POKEing into programs, try setting F = 0 TO 8 and run the program
again. LIST it, and then try to edit your listing. The ZX81 may crash,
and if your screen blanks out or produces other strange effects you will
have to reset it by pulling out the power supply plug and re-inserting it.
The Spectrum is more tolerant of this sort of treatment, and will just
give an error message, but the program listing is corrupt, and NEW
will have to be used.
Storing information in a REM statement in this fashion, given that
as you have seen it can be accessed with PEEK and updated with
POKE, can provide a useful alternative to storing data in variables.
The layout of the program listing in memory, starting at a known
address, enables us to write a program which will renumber the
program lines. Here’s the program for the ZX81:
1 REM "RENUM"
2 REM REPLACE LINE AND STEP
30 REM VALUES IF START LINE
45 REM OR STEP VALUE TO BE
DIFFERENT
50 REM RUN IN FAST MODE FOR
121 REM LARGE PROGRAMS
1001 REM **YOU MUST REMEMBER**
1002 REM ***GOSUBS AND GOTOS***
9000 REM ***RENUMBER***
9010 LET RAM=16509
330
9020 LET LINE=10
9030 LET STEP=10
9040 POKE RAM, INT (LINE/256)
9050 POKE RAM+1, (LINE-256*PEEK R
AM)
9060 LET RAM=RAM+1
9070 IF PEEK RAM<>118 THEN GOTO
9060
9080 LET RAM=RAM+1
9090 IF 256*PEEK RAM+PEEK (ВАМ+1
)=9000 THEN GOTO 9120
9100 LET LINE=LINE+STEP
9110 GOTO 9040
9120 LIST
9130 STOP
Modifications for the Spectrum are required as follows: Line 9010
must be edited to read LET R AM = PEEK 23635 + 256* PEEK 23636.
Line 9070 must be changed to 9070 IF PEEK RAM<>13 THEN
GOTO 9060.
Line 9010 sets a variable RAM equal to the start of the program
area. LINE (the line number to start the new listing) and STEP (the
increment of the line numbers) are both set at 10, but could take any
desired values. 9040 and 9050 POKE into the first and second bytes,
which hold the line number, the value 1@. Into the first byte goes the
line number divided by 256, the INT function turning this to an
integer value. If non-integer values are POKEd into an address, they
are automatically rounded, but to the nearest whole number, which
does not give us the desired result if the remainder is 0.5 or greater.
Into the second byte goes the line number less the value in the first
byte, obtained by PEEKing the byte and multiplying by 256.
Lines 9060 and 9070 increment the address and check if the address
contains the NEWLINE (ENTER) character (code 118 on the ZX81,
code 13 on the Spectrum), repeating until a new line is found, which
marks the end of a program line. 9080 adds 1 to RAM, giving the start
address of the next program line.
Line 9090 checks the value (line number) held in this and the next
byte, to see if the process has reached the start of the renumber
program, passing control to 9120 for listing if it has. 9100 increments
the line number by the step value and control is then passed back to
line 9040, and the new line number POKEd into the first bytes of the
next program line.
Notice that the program checks each byte in turn. Another way to
find the address of the end of the program line, which prevents the need
for this, is to use the data about line length stored in the third and
fourth bytes of the program line. To do this, delete line 9080 and
replace lines 9060 and 9070 as follows:
9060 LET LENGTH = PEEK(RAM + 2) + 256*PEEK(RAM + 3)
9070 LET RAM = RAM + LENGTH + 4
This finds the line length, and adds this, plus 4 for the bytes holding
391
line number and line length, to the current RAM value, giving the
address of the first byte of the next line.
Remember, to use a program like this on the ZX81, you should
LOAD it before you start to program, and use RUN 9000 when you
have developed your program. You will also need a STOP instruction
before line 9000 to prevent your program renumbering itself every time
you run it. The REM statements are not necessary to the program in
the listing, of course, but do give the program something to renumber
as a test. Note that GOSUB and GOTO destination line numbers are
not renumbered, and you must edit the lines affected to suit the new
numbering. Take a printer listing or note down the relevant lines before
renumbering! On the Spectrum, a program can be MERGEd with one
already in memory, and added at any time. See Unit W2 for this
facility.
Loading useful programs, Joined into a subroutine or sub-program
toolkit, is worthwhile if you are developing a large program. This
might include, for instance, a sorting routine, error message and
format subroutines. As with the renumber program, which is deleted
after use, any unwanted routines can be edited out.
A utility program like this should obviously have line numbers
9000 + , and the variables used should not be single letter variables, or
even variables such as A9, which might be needed in the main
program.
The program “TOOLS” in the program library illustrates the
principle, and provides a basis for you to add further useful
subroutines. It incorporates a block deletion routine (also listed
separately), which enables easy deletion of any portions of the toolkit
program not required to be easily edited out. This includes the facility
to delete itself!
U3: System Variables
The system variables area of memory 1s a fixed area holding 125 bytes
(ZX81) or 181 bytes (Spectrum) of system variables. These occupy
either one or two bytes, generally, but exceptions include the variable
PRBUFF on the ZX81 (16444 to 16476), which stores 33 characters in
a line, ready for the printer (the printer buffer), the MEMBOT
variable on both machines, which is a subsidiary number store used in
conjunction with the calculator stack, and KSTATE and STRMS on
the Spectrum, dealing with the keyboard and Input/Output
respectively.
Single byte variables store a number between @ and 255 decimal. A
two-byte variable holds a number between 0 and 65535. This is
because the number of bytes available is 2, hence there are 16 bits,
which can store 65536 values (@ is a value). To calculate a two-byte
value in decimal, which we must do because this is how values from
addresses are returned by the computer, we use (value of least
332
significant byte) + 256* (value of most significant byte). Except in the
case of line numbers for program lines, the first byte is the least
significant byte of any two-byte number.
The set of system variables we will look at are those variables which
hold the addresses of the boundaries between areas of memory. Since
some memory areas move around, the computer must know where
each area starts. We can also use this information to find out what the
current state of memory organisation is for use in various ways. Below
are tables of the ZX81 and Spectrum memory maps with the system
variables and their addresses. Note that the system variable names are
Just mnemonics. They are not recognised by the computer.
ZX81: MEMORY MAP WITH SYSTEM VARIABLES
Memory Area System Variable Addresses Contents Returned by:
System
Variables
(Fixed) (16384)
(Fixed) (16599)
Program
Listing
D-FILE 16396/7 PEEK 16396+256*PEEK 16397
Display
File VARS 16400/1 PEEK 1649@+256*PEEK 16491
Marker Byte
(Single byte containing CHR$ 128)
E-LINE 16404/5 PEEK 164044256*PEEK 16495
Work
Space
STKBOT 16410/1 PEEK 16419+256*PEEK 16411
Calculator
Stack
STKEND 16412/3 PEEK 16412+256*PEEK 16413
Spare
Memory
Machine
Stack
Gosub
Stack
The size of various portions of memory occupied on the ZX81 can be
found by entering (as direct commands) the following:
(Stack pointer-not accessible with BASIC commands)
ERR-SP 16386/7 PEEK 16386+256*PEEK 16387
RAMTOP 16388/9 PEEK 16388+256*PEEK 16389
Program listing: PRINT PEEK 16396 + 256*PEEK 16397-16509
Program, variables, display file and system variables:
PRINT PEEK 16404 + 256* PEEK 16405-16384
Approximate memory left for program:
PRINT PEEK 16386 + 256*PEEK 16387 - PEEK
16412 — 256*PEEK 16413
333
This returns only the approximate number of free memory bytes, since
it does not take into account the size of the machine stack, because we
cannot access the stack pointer. Actual memory is always less than the
value returned.
SPECTRUM: MEMORY MAP WITH SYSTEM VARIABLES
Memory Area System Variable Addresses Contents returned by:
P-RAMT 2373273 PEEK 23732 +256*PEEK 23733
User Defined
Graphics
UDG 23675/6 PEEK 23675 +256*PEEK 23676
RAMTOP 23730/1 PEEK 23730 +256*PEEK 23731
STORAGE
Note that various marker bytes are used to separate areas of memory,
as indicated. Program length (listing only) is given by (PEEK
23627 + 256*PEEK 23628) - (PEEK 23635 + 256*PEEK 23636), i.e.
VARS less PROG. Program and variables memory requirement is
given by E-LINE less PROG, with the PEEKs required again as given
above. All memory areas below 23734 are fixed, with their addresses
being as given in the previous Unit (see the Memory Map diagram).
Without the microdrive, CHANS will be fixed at address 23734. An
alternative method of determining free memory left on the Spectrum is
to use the following, which uses a routine in the ROM memory. The
Not accessible with BASIC
Not accessible with BASIC
STKEND 26353/4 PEEK 26353 +256*PEEK 26354
STKBOT 26351/2 PEEK 26351 +256*PEEK 26352
WORKSP 23649/59 PEEK 23649 +256*PEEK 23659
E-LINE 23641/2 PEEK 23641 +256*PEEK 23642
VARS 23627/8 PEEK 23627 +256*PEEK 23628
PROG 23635/6 PEEK 23635 +256*PEEK 23636
CHANS 23631/2 PEEK 23631 +256*PEEK 23632
Fixed (23734)
334
number of bytes of free memory 1.е. the size of the spare memory
section, is given by PRINT 65536 - USR 7962.
We can use the system variable VARS to determine how numbers
are stored in the computer. Each different type of variable needs to be
identifiable as the correct type, 1.е. as a loop control variable, as a
string variable, etc. This is done by altering the first three bits in the
appropriate letter codes. (Bits in a byte are actually numbered right to
left, starting from 0. In the eight bit byte 00100000 , for instance, bit 5
is set as 1. Bits 5, 6 and 7 in the byte are the ones referred to above.)
On the Spectrum, all letters in variable names are taken as lower
case. These letters all have bit patterns starting 011. . . , codes being
97 to 122. The ZX81 letter codes all start with bits 001 . . . , codes 38
to 63. Check the binary equivalents of the letter codes to confirm this.
Since these three bits are always the same, the computer can alter them
as a signal to indicate which type of variable is being called by a
particular variable name, which may be the same as the name of some
other type of variable (e.g. A as a simple variable, A(5) as an array
variable, A$ as a string variable). The patterns of bytes used are as
follows:
Single character variable did...
Multiple character variable 101...
Loop control variable Lion
String variable BID. .....
Numeric array variable 100.....
String array variable (BI PS
Because the codes for the letters have different values on the ZX81 and
Spectrum, the effect on the value stored in the byte is different. After
we've discussed exploring the ways variables are stored, the form for
each type of variable is given, with the change in the letter code noted
for both the ZX81 and Spectrum.
The next program inputs a value for the numeric variable A. This
will be entered into the VARS area as the first variable stored. Line 30
PEEKs the value of the VARS system variable, and adds the value of
the loop variable F, then PEEKs this address. The first value returned
by the expression in brackets (F = 0) is the address of the first byte of
the variables store. For a numeric variable on the ZX81, this holds the
name of the variable, stored as its Code + 64, if the variable name is a
single character. On the Spectrum it 1s stored as the code of the /ower
case letter, unchanged. Key in the program and input various numbers.
10 INPUT A
20 PRINT "A-";A
30 FOR F= 0 TO 5
49 PRINT PEEK (PEEK 16400--256%Р
EEK 16401 +F)
50 NEXT F
68 GOTO 10
235
Spectrum users: change the PEEK expression to:
40 PRINT PEEK (PEEK 23627 + 256*PEEK 23628 + F)
Input 1.5. The display will be like this:
ZX81 Spectrum
А-1.5 А-1.5
102 (= Code А + 64) 122 ( = Code of lower case a)
129 (5 byte number follows) 129 (5 byte number follows)
64 64
0 0
0 0
0 0
Change the variable name in line 10 to confirm the code. The first byte
of the 5-byte number is the exponent byte, the following four are the
mantissa, the number the exponent acts on to get the numeric value.
The Spectrum has a special form of this for integers. (See below for
more on numbers.)
Change the variable name to, for example, AB5, or other variable
names with more than a single letter in the name, and run the program
again. You can then confirm that numeric variables are stored in these
forms:
Single Character Variable
1 byte 5 byte number
Code Exponent Four Mantissa bytes
+64 7Х81 byte (S = Spectrum)
+9 s
Multiple Character Name Variable
1 byte 1 byte (for each character) 1 byte byte numbe
Code Code Exponent Four Mantissa bytes
+128 2Х81
+64 5
First character and last character only are stored as code plus values
indicated. Other characters are stored as the standard character codes.
The other forms of variable are stored in the byte sequences shown
below. Write programs to confirm these memory arrangements. You
will need a loop that prints the correct number of bytes. The FOR-
NEXT sequence, for example, which takes 18 bytes, can be simply
programmed by deleting lines 10, 20 and 60 in the program above, and
changing the loop to @ TO 17.
336
Loop Control Variable
5 b e numbe ° 2
Code Start value Limit value Step value Line number
+192 Zx81 for next jump
+128 S
The control character is stored as code + 192 on the ZX81, + 128 оп
the Spectrum. The value is incremented or decremented by the step
value each time the NEXT instruction is executed, and the value
checked against the limit value after each such change. The line
number (stored as more significant byte first, as are the program line
numbers) is the line number of the FOR...TO instruction plus 1, as
this is the destination line for the NEXT instruction to jump to.
String Variable
The single letter name is stored as the code less 32 on both the ZX81
and Spectrum. The number of characters is what is read by the LEN
instruction. For a null string, this is zero, and no character bytes are
stored.
Numeric Array Variable
1 byte 2 bytes 1 byte 2 bytes 2 bytes 5 bytes each eleme
Code Number of bytes umber of Size of Size last
+96 2Х81 following dimensions first dim. dim.
+32 S
Notice that an array such as A(7) is a single dimensioned array. (It will
require 1+2+1+2+(7*5)=41 bytes.) The bytes storing the size of
each dimension enable the computer to keep track of a multi-
dimensioned array stored in a linear sequence. For example, DIM
A(3,3) sets a sequence of the eight data bytes, plus 9*5 bytes to hold:
t — Te —P 1.3
ae 2,1 — 2,2 — À 2.9
Cop 21e 22 eni
Work out how a 3-D array, say A(2,3,4) will be stored.
337
String Array Variable
1 byte 1 byte 2 bytes
No. of |Size of first
dims. dim
2 bytes
Ho. of bytes
following
2 bvtes 1 byte per chy.
Length of Code
strings
You should now see why string arrays must have fixed length strings,
since otherwise the computer could not use the length of string datum
to step through the linear sequence to find the appropriate set of
character codes making up an element in the array.
The next manipulation we will look at concerns the way the ROM
memory holds the characters to be printed on the screen.
Starting at address 7680 on the ZX81, and at 15616 on the
Spectrum, each character is held in a sequence of 8 bytes of memory.
The binary number of each byte represents, in this case, a sequence of
075 and 175, which hold the pattern of the character, corresponding to
the 8 x 8 grid of points in each character cell on the screen which is used
to print a character.
If we take the letter A, for example, it 1s represented like this:
DECIMAL BINARY
NUMBER NUMBER
0 00000009
60 00111100
66 01000010
66 01000010
126 01111110
66 01000010
66 01000010
0 00000000
А zero is read as an instruction to leave blank the corresponding point
on the screen, and a 1 indicates it is to be blacked in.
The following program will illustrate the principles. It takes one of
the 8-byte sequences of numbers stored in ROM and gives the decimal
and binary forms of these numbers. The pattern of ones can be seen.
Remember Decimal 0-255, Binary 00000000 to 11111111, is held in
each byte. The relevant portion of memory is accessed by using the
code of the character concerned. Starting at address 7680 on the ZX81,
the first of the addresses for any character is given by 7680 + CODE
(Character)*8. The eight addresses are then PEEKed one by one, and
the decimal number given then the binary form printed out. Lines 110
and 130 convert the decimal to binary and print it.
Whilst the Spectrum characters are held at a specific address in
ROM, the system variable CHARS, which is at addresses 23606 and
23607, holds the start address of the character memory sequence, and
338
can be POKEd with different values to start the sequence elsewhere in
memory. This can be used to define a new start point for the character
set in RAM, and define a whole new character set on the Spectrum, in
addition to the facility for user-defined graphics (which will be dealt
with in Unit W2). CHARS returns a value which is the start address of
the characters, less 256. The character set that is stored in ROM starts
with the Space symbol (code 32) and runs in sequence to © (code 127).
To access the right sequence in ROM, we must use the start value
given by CHARS, which is 15360, plus the character code multiplied
by 8, just as on the ZX81. The fact that CHARS points to 256 bytes
below the start of the printable character set adjusts for the fact that the
first character that can be accessed has code 32 (since 32*8 = 256).
For the program below, therefore, Spectrum users need to put LET
A = 15630 in line 10, which is the normal value given by PEEKing the
CHARS system variable, and the right address in ROM is accessed.
10 LET A=7680
20 PRINT “INPUT A CHARACTER"
30 INPUT А5
40 CLS
50 LET C=CODE А5
60 LET D=8*C+A
70 FOR X=0 ТО 7
80 LET L=PEEK (D+X)
90 PRINT D+X;TAB 6;L
100 FOR Z=18 TO 11 STEP -1
110 PRINT АТ X, Z;L-2*INT (L/2)
130 LET L=INT (L/2)
140 NEXT Z
150 NEXT X
If we add:
120 IFL-2*INT (L/2)- 1 THEN PRINT
AT X,Z +10; “Ш”
we can print out a large version of the character. The routine will only
work for the standard characters and graphics (codes 1 — 63 on the
7Х81). Inverse characters and functions on the ZX81 are not held in
this form. All Spectrum characters up to code 127 can be accessed.
We can use this principle to produce any size character we want,
within the limits of the screen.
The next program allows a string of up to 4 characters to be printed
out. You should be able to follow the same steps in this program as in
the previous one - the method is essentially the same, working on a
string of characters, rather than a single character, and only using the
print routine. To fit 3 lines of 4 characters (which would take 24 lines)
we neglect the first (top) byte, since this is blank for all the letters and
numbers. This lets us fit 3 lines in, but graphics characters will look
strange, since they do use the top line. A different method is used to
read out the binary values for printing. To avoid complex
manipulations of PRINT AT values, which would be required if we
339
used the system in the previous program, each line of the ROM is
checked for each character in turn across the line, which enables a
continuous PRINT operation.
Each binary value is checked in turn to see if it is Ø or a 1 by doubling
the value of X (line 180), so that it is either >128 (1) or <127 (0). Line
150 takes 128 away if a 1 is found. If you do not understand this
process, take any binary number and trace the operation through lines
120 to 190.
© REM "BIGFREINT"
& REM xALLüWS = LINES OF 4
#CHARACTERS EY OMIT-
*TING TOF LINE CELANE
*FOR LETTERS AND
xNLUMEERZ» OF xz GRID
10 DIM Ac43
20 PRINT "INPUT STRING (МАХ 12
LETTERS / МОМЕЕЕ >"
25 INFUT АФ
30 ELS
35 FEM *FOR EACH LINE*
40 FoR Fzi TO 3
= REM xGET CODE INTO ARRAY *
xFOR EACH LETTER %
SO FOR ісі TO 4
во LET ACLI= CODE АСЕ?
70 NEXT L
75 REM xUFDATE At
So LET А%=А%(5 TO 3
ез REM «BYTES 1 TO 7 OF *
* ж ж ж ж
#ITHARACTER IN ROM +
ЭО FOR B=1 TO 7
95 REM *FOR EACH LETTER OF %
*LINE *
100 FOR C=1 ТО 4
105 REM *GET BYTE VALLE
110 LET X= PEEK (7@80+A(C) #8+B)
115 REM #FOR EACH BIT*
1209 FOR V-O Tü 7
125 КЕМ *IF ZERO THEN JUMP
190 IF Х«128 THEN GOTO 170
140 PRINT "Ш";
145 REM #DECREMENT CHECK *
жУЙІМЕ +
150 LET Х-Х-128
160 GOTO 180
170 PRINT " "i
120 LET Х-Хжу
ісе REM xNEXT BIT*
190 NEXT V
19% FEM %МЕХТ LETTER OF LINE*
200 NEXT C
205 REM xNEXT BYTE OF RüOM*
210 NEXT Ë
215 REM *NEXT GERDOLF OF 4+
220 NEXT F
220 REM #*ЕМП++
340
Spectrum users must insert 15360 in place of 7680 in line 120.
The program, ‘‘HEADLINER”’ in the program library, uses the
character array in ROM to print banner headlines on the printer. If
you inspect this program, you will see that it has a method of enabling
the inverse characters of the ZX81 to be printed by changing them into
normal characters (using CHR$(CODE А%-128)) to access the
pattern in memory, then reversing it again when it comes to print it.
RAMTOP may be set to a lower value to give memory space outside
that usually used by the operating system. This has an application
which is occasionally useful on the ZX81, regarding the use of CLS
after SCROLL has been utilised. This does not apply on the Spectrum.
Clearing the screen can take a long time after scrolling. Try this to
illustrate:
10 FOR F=1 TO 30
20 SCROLL
30 PRINT "XXXXXXXXXXXXXX'
40 NEXTF
50 CLS
This is due to the fact that SCROLL interferes with the way the display
file is set up on a ZX81, with more than 3.25k of RAM available — with
a full screen of spaces where no characters exist. A PRINT line after
SCROLL is just the required length, with nothing filling up the line if
there are no characters. To clear the screen, the ZX81 counts up 24
new lines, then inserts spaces to recreate a full display file. If less than
3.25k are available, an empty screen is just 24 newline characters.
RAMTOP is set with 0 in address 16388 and 128 in 16389 оп switch-
on (0 + 256* 128 = 32768, the address of the first non-existent byte).
POK Eing values to set RAMTOP below 19634 (16509 + 3.25k) will
set up the minimal display file and CLS will act instantly. Your
program must be less than 3.25k (say 3k as returned by the commands
given above). The convenient value to use is 76 poked into 16389. This
sets RAMTOP as 0 (value of 16388 unchanged) + 256*76 = 19456,
which is rather more convenient than POKE 16388,76 followed by
POKE 16389,177 (177 + 256*76 = 19633). Insert 45 POKE 16389,76
into the program above and run it again. Note that if you NEW the
program and then key in PRINT PEEK 16389, you will still get 76.
RAMTOP must be re-set by POKEing the correct value (128) or by
switching off and on again to re-set.
On the Spectrum, RAMTOP is moved using CLEAR. The
instruction CLEAR (N) resets RAMTOP to the address given by N.
RAMTOP is reset to this value, and remains at this address until reset
by CLEAR (or switching off and on again.) It is not reset by NEW.
The procedure given below for storing data above RAMTOP is less
useful than it is on the ZX81, because the Spectrum can MERGE a
program with another LOADed in from tape (see Unit W2). This
341
program can be mostly data (although it must have program lines).
However, this method will work on the Spectrum, and shows the
technique of moving Information around in memory. If you progress to
machine-code programming, this is one way in which you can store
machine code.
RAMTOP may be moved so as to reserve space at the top of
memory. On the ZX81, this area will not be affected by NEW or
CLEAR, or the automatic NEW that occurs with LOAD. It can be
used to store data for use by another program, after the data have been
defined by a previous program. This procedure, available with less
complications on some computers, is performed as follows on the
ZXO1.
i) New values are POKEd into the RAM TOP system variable, so
that the system considers the top of RAM to be lower than
address 32767. This reserves space above the new RAMTOP
value. NEW is then used. POKEing RAMTOP has no effect
until NEW has been used. How much space is reserved depends
on the number of bytes of data we require to store. (Spectrum:
See above for resetting RAM TOP.)
п) The program to use the data must have been written and stored
on cassette. This has instructions to copy into the variables area
the data stored. It must initzalise the same variables or arrays for data in
the same sequence as the program which provides the data.
ii) The program to store the data intialises the arrays or variables
for the data first, before any other variables. The program is then
run. The required number of bytes are taken from the start of
the variables area (found using VARS), and copied to the area
above RAMTOP (found using RAMTOP).
iv) Program 2 is then loaded. It initialises the variables as did
program 1, finds VARS and RAMTOP, and reverses the
procedure, PEEKing RAMTOP and POKEing the values
found into the variables area. It can then proceed to use the
data.
The amount of memory needed for storage is calculated from the
information given above about the method of storage of variables. As
an example, let us assume we want to store an array D(20) for use by
another program. We will use this as a short example program. In
practice, the technique will require a second program to use the data to
have been written and SAVEd, but the examples are short enough to
key in.
Reference to the information about variables shows us that an array
D(20) requires 106 bytes. On a ZX81, we must set RAMTOP as
32768 — 106 = 32662. This is the address of the first non-existent byte,
and will be the address of our first storage byte. To set RAM TOP to
this value, we POKE 16389,INT(32662/256) as a command, followed
342
by POKE 16388,32662 – 256*INT(32662/256). Of course you could
use the computer to work these out beforehand, and POKE the values
directly. NEW the computer, then enter this program and run it. On
the Spectrum, RAMTOP is set with CLEAR, and can be done simply
by using:
CLEAR (PEEK 23730 + 256* 23731 – 106)
5 REM "DSTORE"
10 REM **DATA ABOVE RAMTOP**
20 DIM D(249)
30 FOR F-1 TO 26
40 LET D(F) =F*F
50 NEXT F
60 LET VARS=PEEK 164004256*PEE
K 16461
70 LET RAMTOP-PEEK 16388+256*P
EEK 16389
80 FOR Е=0 TO 105
90 POKE (RAMTOP+F) ,РЕЕК (VARS+F)
100 NEXT F
The first active line (20) dimensions the storage array. The loop of lines
30 to 50 merely insert some values into the array. Lines 60 and 70 find
the values of VARS and RAMTOP. The loop of lines 80 to 100 stores
each byte of the variables store that contains array D above
RAMTOP. Spectrum users must insert the correct PEEKs in lines 60
and 70 to get the values of the VARS and RAMTOP system variables.
The same must be done with the data retrieval program below.
Now use NEW, and enter the program to retrieve the data. This
reverses the procedure. After initialising D(20), and finding VARS
and RAMTOP, it POKEs the value of each byte stored above
RAMTOP into the bytes of the variables area containing the array.
Lines 70 to 80 print out the array values.
1 REM "DFEICH"
5 REM **RETRIEVE STORED DATA
**FROM MEMORY ******
10 DIM D(29)
20 LET VARS-PEEK 16400+256*PEE
K 16401
30 LET RAMTOP-PEEK 16388+256*P
EEK 16389
40 FOR Е-й TO 105
50 POKE (VARS+F) ,PEEK (RAMTOP+F)
60 NEXT F
70 FOR F=1 TO 20
80 PRINT D(F)
90 NEXT F
On the ZX81 only, you can use CLEAR: the array will be wiped from
memory, but remains safe above RAMTOP. Running the program
again will retrieve the data once more. This is obviously a technique
useful not only for passing data between programs, but also for
allowing CLEAR to be used and still having current data (i.e. that not
343
assigned by LET statements) preserved. This does not apply to the
Spectrum, since CLEAR re-sets RAM TOP.
The complete list of system variables for both the ZX81 and the
Spectrum is given in Appendix V. The timing variable FRAMES is
used in the “КЕАСТ”” program analysed in Unit V3.
MORE ON NUMBERS AND COMPUTERS
The way in which numbers are manipulated by the operating system in
a computer does not concern us here, but the way numbers are held,
and their form, are important in computing, even if the precise manner
in which calculations are carried out is a separate topic. We will deal
here with enough detail of the binary system to enable 5-byte floating
point to be understood.
We briefly introduced the binary system earlier. To explain further
the use of a system using powers of 2, and how any number can be
represented % a certain level of accuracy, key in this program:
10 REM "POWERS OF TWO"
28 PRINT "POWERS OF Two"
30 PRINT "------------- "
40 PRINT "2**N";TAB 10; "М№";ТАВ
16;"2** -N"
50 PRINT
60 PRINT TAB 6;"1 0 1.9"
70 FOR F-1 TO 16
80 PRINT TAB ( 17-LEN STRS (2**F
));2**F;TAB 10;F;TAB (14+(F
>3));2%%-Е
90 МЕХТ Е
(Replace ** Бу # for the Spectrum at each occurrence in the program).
You will get a display like this:
POWERS OF TUO
mx xM ч eee -M
1 & 23.
c і e.
41. е е.гБ
б a G. 1
15 4 . 0825
32 5 a 93125
64 ы «"ӘӨзбесе
128 а „ гат >=
256 а |. yl ==
S123 э -дәлзезіге
1924 18 -@B@2907SES5625
2048 із „ 5345525583065
4995 12 PAAS L 14065535
6192 13 |. їз YT = 71
163524 із „ асас 22351355
32768 15 „ зз ЗЫ Г БН
65536 isc «"Әсоелкгезуаә
Notice that we have positive powers of two оп the right, giving integer
values, and negative powers, giving fractions which are represented as
‘decimal decimals’. The emphasis in the comment above about
accuracy stems from the fact that there are limits to the accuracy
obtainable with every number system. The fraction 1/3 is never
344
accurately represented in the decimal system, however many decimal
places are used. The same goes for many numbers in both decimal and
binary notation. If you study the display it should be apparent that
with the binary system, only numbers equal to certain decimal values
are accurately represented. Decimal .6875, equal to 1/2 + 1/8 + 1/16 is
accurately represented by binary .1011, for example, but with a single
byte (8 bits), any number varying by .001953125 (2-7) above or below
the value represented in the byte will appear the same to a computer
reading this byte.
To increase the accuracy of representation of numbers, a larger
number of bytes is needed. This also allows larger numbers to be dealt
with. The ZX81 and Spectrum use ‘‘5-byte floating point’’
representation of numbers. The ‘FLOAT’ program gives the decimal
value held in each byte of the five by PEEKing the variables area:
1 REM *FLOAT*
2 REM FRINTS FLOATING FOINT
FORM OF A NUMBER
10 PRINT "ENTER A NUMBER"
20 INPUT N
ЗО PRINT "THE NUMBER "FN" IS
HELD» "IN THE 7Х681 А5:-"
40 FOR F=1 TO Š
45 REM FEEKS START OF VARIABLE
STORE (VARS) AREA IN MEMORY
SO PRINT FEEK С PEEK 16400+2546
ж PEEK 16401-4F);" "3
60 NEXT F
On the Spectrum you should change Line 50 to read PRINT PEEK
(PEEK 23684 + 256*PEEK 23685 + F). Input only non-znteger values
(we'll explain why this is the case a little later).
If you input 2.4, you will get a screen display of:
130 29 153 153 154
Try other numbers. There is no obvious pattern to the decimal values,
other than the first number not varying much from around 128 unless
you input very large or small numbers. This is the exponent byte (as with
the E notation). The next program, “ЕТУЕВҮТЕ”, displays the
mantissa number (the other four bytes) in decimal and binary form,
and the exponent byte in decimal form:
10 REM "FIVEBYTE"
ZO PRINT “INPUT NUMBER"
ЗО INPUT N
40 PRINT “NUMBER="7N
50 LET EXP= PEEK (1+ PEEK 1640
O+256% PEEK 16401)
60 PRINT “EXPONENT="; EXP
70 LET Р=ЕХР- 128
80. IF P <> -128 THEN PRINT “2
жж Hers Mats ++ Р
90 IF EXP=0 THEN PRINT “USED F
OR ZERO ONLY"
345
100 PRINT "MANTISSA BYTES: -"
110 FOR F=2 TO S
120 PRINT TAB (F-2)#5; PEEK (F+
PEEK 182400-256% РЕЕК 16401);
130 NEXT F
140 ЕСЕ Е=2 TO S
150 LET D= PEEK ¿(F+ PEEK 16400+
256% PEEK 16401)
160 LET Es$z""
170 LET L= INT (0/2)
120 REM LET АФ=("1" AND П-72 +
C"O" AND П-2ж-0)
181 LET A$- ZTR$ (D-Z*L>)
190 LET BS=A$+E%
200 LET IL
210 IF 050 THEN GOTO 170
220 IF LEN E$Z8 THEN LET E$z"oo
o00000"c1 TO (8- LEN E$))+EËE%$
230 FRINT TAE (F-20*8; E$
240 NEXT F
(Once again, on the Spectrum change ** to Î at every appearance.
Line 50 needs to be changed to read LET EXP = PEEK (1+ PEEK
23684 + 256* PEEK 23685) to give the start of the Spectrum variables
area. Change 16400 to 23684 and 16401 to 23685 in lines 120 and 150
also.)
A number stored in 5-byte floating point notation has an exponent
byte, which acts, as with the decimal E notation, to shift the binary
point along to the correct place.
The exponent value is stored as exponent plus 128, and can hence be
negative or positive. It works in powers of two, and the value of this
(exponent raised to the power of two) is given in the program. The
representation of zero has a special form, such that the exponent is 0,
and the values of all the other bytes is also zero. The value stored in the
exponent byte is thus between 1 and 255, giving possible exponent
values between - 127 and +127. The range of numbers covered 15
then what would be presented if our POWERS ОЕ TWO” program
went on to 127 rather than just 16.
The mantissa value (represented in the next four bytes) is converted
to the numeric value by multiplying it by 2 raised to the power of the
exponent: N - M*2*, where M is the mantissa value and e is the
exponent (value stored in exponent byte less 128). This process can
also be considered as moving the binary point the number of bits given
by the exponent.
The mantissa bytes are considered as a single sequence of binary
digits, with the binary point at the beginning. The program gives the
values stored in each byte (as with the “ЕГОАТ”” program), and then
converts to binary to give the mantissa sequence. Since the first bit of
the mantissa sequence is always 1 (the mantissa 1s always between .5
decimal and 1 decimal, but never reaches 1, i.e. 0.5< = m<1) the first
bit 15 used as a зол bit. If the number is positive, the first bit is changed
to Ø. If it is negative, the first bit is set to 1. This is used as a means of
handling negative numbers, since all the numbers generated in the
346
floating point notation are positive, and an equivalent to the ‘ — ' sign is
needed to show negation.
Input 0.75 into the computer when prompted. The display will be
like this:
INPUT NUMBER
NUMBER - 0.75
EXPONENT - 128
2**0-1 ( 4 on Spectrum)
MANTISSA BYTES:
64 0 0 0
01000000
00000000
00000000
00000000
The evaluation is as follows. The first bit is a zero in the mantissa. This
indicates a positive number. The first bit is changed to a 1, and the
value of the mantissa is now .11000...0. The trailing zeros are ignored.
Binary .11 is decimal 0.75 . The exponent value is 0, and 2 raised to
the power 0 is 1. So we have a value of 0.75*1 = 0.75. If you input
— 0.75, the display is identical except for the first mantissa byte ( + 128)
because of the first bit now being 1, and the first mantissa bit, changed
to 1 to indicate a negative number. This is left as 1, and evaluation
then proceeds as before.
Now input 3.75. The exponent is 130, 2**2 ( Жоп Spectrum) is 4,
and the mantissa bits hold the sequence 01110... The first bit changes
to 1, and this gives .1111 binary, 0.9375 decimal. 4*0.9375 = 3.75 .
The alternative way of viewing the process is to consider the exponent
as moving the binary point along. In this example, we have the
sequence .1111, and since the exponent value is 2, the binary point
moves the same number of places to the right, to give 11.11 , which is
3.75 in decimal. In the previous case, with 0.75, the exponent value
was 0, so the point was not moved, and the bits were .11 . Negative
exponents move the binary point to the left, adding zeros.
The Spectrum has a special representation for integers in the range
+ 65535 to — 65535, in which the first byte (exponent byte) is zero, as
is the fifth byte. The second byte acts as a sign byte, holding 0 if the
number is positive, and 255 if the number is negative. The third and
fourth byte hold the number (least significant byte first). You can use
the **FIVEBYTE'' program to investigate this representation if you
are using a Spectrum.
To illustrate rounding errors and an otherwise puzzling aspect of the
representation of numbers, input 1/2 into the ‘‘FIVEBYTE”’
program. We get exponent byte = 128, exponent 128 ~ 128 = 0, and a
zero in the first bit. This changes to a 1, and we have .100.... Exponent
Is zero, so we don't move the binary point and get .100...., which is
347
0.5, and equal to a half. Thus far all is well. If we like, we can consider
that we got .100.... and multiplied it by zero to get our half. As we said
above, the two processes are identical. But now input 0.5. This should
be the same, but instead we get exponent equalling 127, and 0111....1
(thirty-one 1’s)! We seem to have an error. However it is a pretty small
one, though it explains why the computer rounds its numbers. To
avoid considering % as not equal to 0.5 it has to take into account the
fact that the decimal to binary conversions have these inaccuracies.
Binary addition of two 1’s causes a @ to be placed in that byte, and a 1
is placed in the next column to the left. (If you’re interested, the other
rules for addition are: 1 and 0 give 1, 0 and 0 give 0, three ones (1, 1
and a carried 1) give 1, carry 1 to next column on the left. Try a few
simple sums!) This means that if a 1 is added to the least significant bit
of our sequence of ones:
пека жа 1111
1
0
I. (carry)
0
1 (carry)
0
1 (саггу)
etc
all the 1's will become zeros, and the last carry would put 1 in the first
bit, which would make it the same representation as the % sequence,
but this also has a 1 in it. This forces a carry to a non-existent bit to the
left of the mantissa. This gives us 1.0 as our binary, and the exponent
shifts this (exponent = - 1) to .100...., which is correct. Or we сап
consider this as 1.0 binary (1 decimal) multiplied by 2 ` '(0.5). So the
error is in the least significant bit. The size of the error is thus 2~*’, the
value of the right-hand 1. This is fairly small! The computer rounds
numbers to ensure these inaccuracies do not cause errors. It considers
numbers equal if the difference between them is less than a certain
amount. Rounding errors can still build up under some circumstances,
however, and it is important to note that no computer performs totally
accurate arithmetic, except with integer values.
You may be a little overwhelmed by numbers at this point, but
before we give them a rest we should introduce you to another
numbering system — Hexadecimal.
This is another numbering system much used in computing,
although it has no practical application for us at present since the
348
Hexadecimal system (often abbreviated to Hex) is primarily used in
machine-code programming which is beyond the scope of this text.
Whereas binary is base 2, and decimal base 10, hexadecimal is base 16.
This is a convenient system for computers using 8-bit words, since
16 x 16 = 256. Any value which is held in a single byte can thus be
represented by a two-digit hexadecimal code. The system uses the
digits 0 to 9, and goes on with A, В, C, D, E and F, to represent the
numbers 1 to 16. Here is how the system counts:
Decimal Hexadecimal
Ø 0 (9 x 164)
1 1 (1 ж 16°)
9 9 (9 x 16^)
10 A (10 x 164)
11 B CUL 167)
15 F (15 x 167) ó
16 10 ( 1 16.) +, ( Ø x 164)
17 11 Ci x15)4CI1x]l15 )
25 19 (Tx 161) + C Ox 165)
26 1A lx 167) + (20 x 167)
31 lF (XX x 161) + #18 ш 160)
32 20 (o2 167). + í Өле 16”)
154 9A ( 9 x 161) + (10 x 164)
155 9B ( 9 x 167) + (11 = 18")
159 OF (ox 161) + (15 x 164)
16¢ AG (16 x 16) + (Ø x 16’)
250 FA (18% 16°) 4°16 x 167;
254 FE (15 x 161) + (14 x 165)
245 FF СІЗ «x 16°) = CS ж 167)
As with any number system, we could go on (256 is 100 hex, etc.), but
the use of hexadecimal is in representing binary numbers in a more
convenient form than strings of 1’s and 075, which are difficult to read
and easy to make mistakes with (unless you аге a computer’).
The advantage of hexadecimal notation is that any 8-bit binary
number is convertible to hex far more easily than into decimal, due to
the relationship of base 2 and base 16 numbers. Base 16 is base 2*, and
349
this means the 8 bits of a byte can be divided into two sets of four bits
(remember 1111 binary = 15 decimal = Е hex) and converted to the
corresponding two hex digits. For example, the number 116 decimal is
in binary 01110100. Split into two groups of four bits, 0111 and 0100,
we convert each group to a hex digit.
0111 binary (7 decimal) is 7 hex
0100 binary (4 decimal) is 4 hex
The number in hex is 74. Check this: (7 x 16) + (4x 16°) = 112+4= 116.
Again, 93 decimal is 01011101 binary:
0101 binary (5 decimal) is 5 hex
1101 binary (13 decimal) is D hex
The number in hex is 5D. (5 x 16) + (13 x 16°) = 80 + 13 = 93
To avoid possible confusion when both hexadecimal and binary
numbers are being used, a small h should be used after a hexadecimal
number. Our examples above would be 74h and 5Dh. Hex numbers
are grouped in twos, and the leading zero should be used for numbers
less than 16 decimal, so that 12 decimal should be written 0Ch, and not
C or Ch.
Similarly, numbers up to 65535 decimal (held in two bytes of
binary), are representable with four hex digits. 11111111111111111
binary is thus FFFF hex, 10101101001101110 is 1010 (A)/1101
(0)/0011 (3)/1110 (E): AD3Eh. Work out the value of this in decimal.
The program library has programs which convert decimal to hex and
vice versa (“НЕХПЕС” and ‘‘DECHEX’’). Analyse these programs
to see how they work. The CODE and CHR$ functions are used to
check the hex notation, or produce it.
Exercises
1 Alter the “СНКОМ” program to print just the large character,
and then the inverse form next to it, by reversing the printing
instructions for the character to be printed when a 0 or 1 is found
in the binary form.
2 Using the “BIGPRINT” program as a basis, store the charac-
ters of each line of the large characters in an array, so that a
scroll routine can be used to cause the message to disappear off
the top of the screen line by line, and re-appear at the bottom.
3 Write programs to store a string array above КАМТОР, and
then retrieve it. Use a three-dimensional array.
350
PART FOUR
APPLICATIONS PROGRAMS AND
GAMES
ш
3 ЖЕШСИН,
Өре FIFAHSOOBS РИТА ЗА
23127.
SECTION V: APPLICATIONS PROGRAMS
V1: Programming for Applications
You have been introduced to the full set of ZX81 BASIC instructions.
Spectrum users have some additional instructions in the Spectrum
superset of BASIC, but we have attempted to show how all necessary
operations can be performed on the ZX81 and the Spectrum merely
makes some operations easier to implement. We have covered a range
of operations, involving loops, lists, array manipulation, sorting,
subroutines etc., and the implementation of control structures. These
are the raw material of programming. The combination of what you
have learned about algorithms, design, program structures,
manipulations and methods with the task you wish the computer to
perform produces an applications program.
There are no rules to derive algorithms. If there were, they could be
coded into a master program that would write our programs for us! We
have illustrated ways of thinking about a problem that can help, but
each program we wish to write presents a unique problem. Familiarity
with the language and control structures, and with existing solutions to
a variety of problems, either other people’s or your own, make it easier
to program. As with most things, the art and craft of programming
becomes easier with practice. The importance of keeping notes about
programs you have written, and on solutions to problems you have
found in analysing other programs, is that it will prevent you re-
inventing the wheel. As you write more programs for yourself, you will
find that you come to recognise the method (or methods - there is
seldom only one way to perform a given task!) by which you can
implement and code each module of your program.
Modular, structured program design methods help to break down a
programming problem to these recognisable chunks, and you wil
recognise more aspects of a problem as having been met (and solved!)
before as you gain experience.
You will also become familiar with the types of data structure
required in a program to make it possible to manipulate the data
efficiently, and grasp more quickly and clearly that, for example, a
given set of data is more efficiently (i.e. easily) handled in a multi-
dimensional array than in separate lists, or that a similar routine in
different program modules could be handled by a single subroutine if
suitable variables were initialised before calling the subroutine.
Experience cannot be transferred, and there is no substitute for
practice, but examples can be given. After the important topic of
writing user-friendly programs has been dealt with in the next Unit, we
give examples of programs written to perform specific tasks, to
illustrate the process of designing applications programs. Games
programming is briefly dealt with in the following Units, since games
393
are a good testing ground for problem-solving and programming
techniques.
V2: Instructions and Input Checks
If you have written your own program, you know which inputs the
program requires, in what form and when. You know, for example,
that when ‘‘ANOTHER СО?” appears on the screen, you must press
the Y key to run the program again.
Now consider what happens if someone else wishes to use the
program (or if you return to it after some weeks). There is not enough
information available to the user. The term user-friendly is applied to
programs which have sufficiently clear and precise instructions to tell
someone who has never seen the program running exactly what to do.
We should always attempt to make our programs at least reasonably
user-friendly. To continue the example of running a program again,
the line:
60 PRINT “AGAIN?”
could be followed by
70 INPUT A$
80 RUN
or
70 IFINKEY$ =" " THEN GOTO 70
80 RUN
Or
70 IFINKEY$-'''' THEN GOTO 70
80 IF INKEY$ =" Y" THEN RUN
or
70 PAUSE 40000
90 RUN
These need different responses. We should use for the first “PRESS
NEWLINE (ENTER) TO RUN AGAIN”, for the second and fourth
"HIT ANY KEY TO RUN AGAIN”, for the third “AGAIN?
(PRESS Y OR М)” or similar instructions appropriate to the program.
We can assume that the user recognises that an input prompt
requires string or numeric input, according to its form, but (as we shall
see later) there may be reasons for requesting a number in string form,
and in any case we must make it clear what is required. We should be
careful to use, for example:
“INPUT FIRST WORD" andnot “INPUT AS"
"ENTERA NUMBER 1 ТО 10° andnot “INPUT X”
"MONTH (1 TO 12)" апа not “MONTH?”
since if the user does not know what A or A§ are in the context of the
program he or she is unlikely to respond correctly, and might try
entering JAN or MARCH for the month.
We should also avoid the use of instructions grouped together:
10 PRINT “INPUT CURRENT, P.D, KNOWN AND
UNKNOWN RESISTOR”’
394
20 ІМРОТА
30 INPUT B
40 INPUT C
30 INPUT D
14 DIM A(10,3)
20 PRINT “INPUT MATRIX”
30 FOR F= 1 TO 10
40 FOR N= 1TO3
50 INPUT A(F,N)
60 NEXT N
7/0 NEXTF
It is very easy for the user to forget which of the inputs is currently
required. The information also fails to include the units of the values
required, and does not print the input values on the screen. We should
use a format like this:
10 PRINT “INPUT CURRENT IN AMPS”
20 INPUT A
30 PRINT “CURRENT = '; A“ AMPS”
49 PRINT “INPUT P.D. IN VOLTS”
50 INPUT B
00 PRINT "Р.О = “ Be" мо"
This provides both clear instructions and visible input values.
A look at any reasonably complex user-friendly program will show
you that a significant portion of any application program is
instructions. Instructions should be concise, but only to a degree that
still provides adequate information.
Expanded instructions can form part of the documentation of a
program, but the program itself must contain the basic instructions
required to ensure correct input and manipulation.
The program ‘‘MATMULT”’ in the program library has a better
approach to the array entry problem. Try to write one yourself, then
compare the two routines.
The combination of good instructions and input checks is the best
method of reducing user error. The human being is less reliable than
the computer, and far more inaccurate results or program crashes
occur due to input error than happen due to bugs in the program,
assuming it has successfully completed a sequence of dry runs.
Checks to reduce the possibility of human error, or prevent bad
effects from it, are the means by which a program is ‘idiot-proofed’ or
‘mug-trapped’. Commercial programs designed for inexperienced
users with no programming knowledge often have as much space
devoted to input checks as to the program proper. We can assume some
awareness in the users of our programs, and trust that they will enter 2
and not TWO, for example, but check routines can ensure that simple
keyboard errors are not passed over. Subtle errors or straightforward
mistakes are less easy to deal with.
3935
It is a simple matter to check that an entered value is within an
acceptable range:
10 PRINT “INPUT MONTH (1 TO 12)"
20 INPUTM
30 IF M>12 OR M«1 THEN GOTO 10
Since the month is to be input as an integer we could add a line to check
this:
40 IF INT M<>M THEN GOTO 16
In fact one line will do it all:
30 IF INT M<>M OR М>12 OR М<1 THEN GOTO 10
Note that if there is an error, using GOTO 10 rather than GOTO 20 at
least indicates to the user that something has happened by re-printing
“INPUT MONTH (1 TO 12)” on the screen. If we used GOTO 20
the user would wonder what had happened, and maybe think that the
year was now required. It is better to have a statement specifically
stating that there was an error in input. To continue our example, we
could have these lines:
30 IFINTM-M AND М< = 12 AND M» = 1 THEN GOTO 60
40 PRINT “INPUT ERROR:RE-INPUT MONTH'
50 GOTO 20
60 PRINT ''INPUT YEAR (AS 82 FOR 1982, ЕТС.)”
‘errr (Rest of program)
The user is informed what is wrong, and told what to do. Make sure
you see why the new line 30 had to have both the relational and logical
operators switched round to make the program work.
To enable re-use of check or error routines it is convenient to place
them in subroutines. The following date entry routine uses a
subroutine to print an error message for a few seconds (line 500) which
is used if any of the checks shows an error. The routine checks the
following:
i) Day of month between 1 and 31 (line 40)
ii) Month between 1 and 12 (line 90)
ш) Year between 1911 and 1998 (line 140)
iv) Whether the year is a leap year, and if it is not, that 29 February
has not been entered (line 190)
v) That days which do not exist in some months have not been
entered (line 210).
Check the logic used in these lines to see how it works. The lines are
good examples of how multiple conditions can be combined, but for
that reason they are a little difficult to follow.
10 PRINT “ENTER DATE"
20 PRINT "DAY?"
38 INPUT D
40 IF D»-1 AND 0<=31 THEN GOTO
70
58 GOSUB 500
68 GOTO 20
70 PRINT “MONTH? (1 TO 12)"
88 INPUT M
356
90 IF М>-1 AND M<=12 THEN GOTO
120
100 GOSUB 500
110 GOTO 70
120 PRINT "YEAR? (AS LAST 2 DIG
115)"
130 INPUT Y
140 IF Ү>10 AND Y<99 THEN GOTO
170
150 GOSUB 500
160 СОТО 120
170 REM *CHECK DAY US MONTH*
180 REM *LEAP YEAR*
190 IF INT (Y+1900) /4) <> (ү+190
0) /4 AND М-2 AND D=29 THEN
GOTO 220
200 REM *SHORT MONTHS*
210 IF NOT ((M=2 AND D>29) OR (
M=4 OR M=6 OR M=9 OR M=11 A
ND D= 31) THEN GOTO 240
220 GOSUB 500
238 GOTO 19
240 REM .....PROGRAM
250 PRINT D;"/";M;"/19";Y
268 REM seoses
278 REM «se cue
400 GOTO 999
499 REM **ERROR NOTICE**
500 PRINT "***INPUT ERROR***","
PLEASE FOLLOW INSTRUCTIONS"
, RE-INPUT REQUESTED DATA".
510 PAUSE 200
520 CLS
530 RETURN
999 REM*END*
The program ‘‘INDATE”’ in the program library uses much the same
routines, but set up as two nested subroutines, so that it can be used in
any program requiring multiple date entries, such as an accounting
program.
It is also a simple matter to put in input checks that print the input,
and invite the operator to check if it is correct, and to re-input if an
error has been made. This is important where multiple data entries are
being made, since an error would otherwise require entering
everything again. As an example, here is a check routine for string
input:
40 FOR N = 1 TO X
50 PRINT "INPUT STRING";N
60 INPUT WŠ (N)
70 PRINT W$ (N)
80 PRINT "IF INCORRECT PRESS E
TO RE-ENTER."; TAB 0; "PRES
S ANY OTHER KEY TO CONTINUE
IF OK."
99 IF INKEYS -"" THEN GOTO 99
100 IF ІМКЕҮ5 = "E" THEN GOTO 5
0
110 NEXT М
397
Rather than check each value, it is sometimes better to wait until all
entries have been made,
and then print them out for checking. This
routine does this for a list of numbers:
10
REM INPUT SPRINT» СНЕСЕ AND C
ОРЕЕСТ ROUTINE FOR LIST
20
190
200
210
220
PRINT “ENTER NUMBERS"
DIM ACz4)
FOR L=i TO 24
INFLUIT ACL)
PRINT AT 3+L-12*(L312)510%(
(2199? АС
230 NEXT L
200 FRINT АТ 21:07 "ALL CORRECT?
CY ПЕ М3"
210 INFUT ES
320 IF E$z"Y" THEN GOTO 1000
330 CLS
340 PRINT "EACH VALUE WILL EE F
FAINTED"; "ENTER NEWLINE IF ik. NEW
VALJE", " IF WRONG, "
350
22,0
1000
ЕПЕ Ғ-1 TO 24
FEINT АТ 21,;07ACF3)
INFUT N$
IF N$z"" THEN GOTO 410
LET ACF3= VAL N$
FEINT АТ 21sO07ACF3;3"
SCROLL
NEXT F
REM *REZT OF FROGRAM*
Spectrum users should delete line 410, inserting 410 POKE 23692, - 1.
The virtue of using string input is that instead of stopping the program
with an error message if an invalid entry is made (a letter, character
that is non-numeric, or more than one decimal point), as occurs with a
numeric input, the string input can be accepted whatever the
characters input. The inputted string must be checked, however, or
else we just get an error message when using VAL to convert to a
numeric value. This requires a routine like the following:
REM "STRINGNUM"
PRINT AT 0,5; "ІМРОТ NUMBER"
INPUT NŠ
LET DP=0
IF NS="" ‘THEN GOTO 100
FOR Е=1 TO LEN NS
IF CODE N$(F)«27 OR CODE NŠ
(F)>37 THEN GOTO 100
IF CODE N$(F)-27 THEN LET D
P=DP+1
NEXT F
IF DP>=2 THEN GOTO 100
GOTO 130
PRINT AT 0,5;"ERROR IN INPU
{н
PAUSE 75
СОТО 1@
REM ...REST OF PROGRAM....
SCROLL
358
150 PRINT VAL NŠ
168 GOTO 10
Spectrum users need to change the character code checks in lines 60
and 70. Change 27 in line 70 to 46. Change line 60 to read IF CODE
N$<46 OR CODE N$ = 47 OR CODE N$>57 THEN GOTO 100.
Change line 140 to read 140РОКЕ 23692, — 1 and line 150 to read 150
PRINT АТ 21,6;VALN$.
Line 20 inputs the string. Line 30 sets a variable to store the number
of decimal points. Line 40 checks that NEWLINE (ENTER) alone was
not pressed, and passes control to line 100 to print an error message if it
was. Lines 50 and 80 set a loop for the number of characters in N$, and
line 60 uses CODE to check whether characters other than numbers
and the decimal point are present, and goes to 100 for an error message
if they are. Line 70 adds 1 to the variable DP for each decimal point
found in N$. After the loop, line 90 sends control to 100 for an error
message if there is more than one decimal point. Line 95 bypasses the
error routine, and line 150 uses VAL to return the number for
printing. At this point, if the number were needed for calculation, a
variable could be set (LET N = VAL N$) to store the value.
Note that an input error causes (line 120) the input routine to be
repeated, after indicating for 1% seconds that an error exists.
V3: Example Programs
This Unit presents some examples of applications programs of various
types, as follows:
1 “КЕАСТ”: Reaction time testing.
2 *BINGO'': Creation, calling and checking the cards for playing
Bingo on the computer.
3 “REF. INDEX”: The calculation of refractive indices from the
angle of deviation and prism angle data produced by
spectrometer experiments.
4 “SERIES”: The summing of a convergent series to a given
degree of accuracy.
5 “СКАРН”: Calculation and plotting of functions, with titles
and scales, to give a hard-copy printout.
6 “ELEMENT”: The calculation of empirical chemical formulae
from the percentage composition of compounds, or the
percentage composition from the numbers of atoms of each
element in the molecule.
7 ‘*CASSFILE’’: Cassette file storage and manipulation, with
printout of cassette files and cassette label printing.
None of these programs are particularly complex (although CASSFILE
is lengthy), and they deal with fairly straightforward applications.
However, the principles involved are valid for any size of program, and
359
the programs themselves demonstrate many of the techniques and
procedures introduced earlier in the text. More examples of
applications programs and useful subroutines are to be found in the
program library provided in the Appendix, but they are not as fully
annotated. The programs here are presented as problems and
solutions, with some discussion of the approach to the problem. The
procedure is then presented, and the derived program.
Please remember that any program can be written in different ways,
even given that the algorithm is exactly the same. This variety of
solutions means that there is never only one correct program.
Spectrum users should note that we have indicated some instances
where the additional functions of the Spectrum can be put to use.
These functions are described in the next Section. After you have
explored the new functions, you should return to these programs and
modify them for practice in the use of these facilities.
1. “REACT”
Problem: To use the computer to assess response times in reaction to a
signal. An average should be taken of a number of timings.
Research the problem: The timing function can use the system
variable FRAMES. A start signal will be required, which should be
preceded by a random delay to prevent anticipation. Computing time
must be allowed for in the result. The number of timings desired
should be input and used to set up a loop.
On the ZX81 FRAMES is a system variable held in 2 bytes, 16436
and 16437. On the Spectrum it is 3 bytes, 23672, 23673 and 23674.
The program can use both bytes on the ZX81 and the two less
significant bytes (the first two) on the Spectrum (since we do not need
to time hours!) This will give a timing period of up to
((256 x 255) 255)/50 seconds in the U.K. and ((256 x 255) + 255)/60
seconds in the U.S., or about 22 and 18 minutes respectively, before
the FRAMES counter, which counts backwards by decrementing by 1
every 1/50 (or 1/60) seconds, reaches zero. This will allow the program
to be used as a timer for longer periods, or modified for use as a
stopwatch program.
Procedure: The program will have a loop structure, determined by the
input of the number of tests required. Outside this loop will be the
instructions at the beginning of the program, and the output of average
reaction time.
This timing module is the core of the program. The input module
(instructions, ‘get ready’ messages and an input for the number of
timings required) and the output module (average time) are easily built
around this. We may proceed to code in a version of this module,
having decided our structure for the program, and test/debug the
timing module, before using the editing facilities to modify this module
as required and code in the input and output modules.
360
The timing module will require the address bytes to be set at a
known value (the maximum, 255) by POKEing values in, and the
values returned by PEEKing these bytes will be used to calculate the
time according to the expression T -((256*(255 - PEEK
16437)) 4 255 - PEEK 16436)/50. (U.S. users must use 60, not 50 in
the expression and the program.) For the Spectrum the first address
will be 23673 and the second 23672.
Our procedure in this simple linear program is as follows:
1 Input Module = 1 Give instructions
2 Input number of tests required (A)
3 Initialise array for timings, B(A)
4 [Initialise variable for total timings, X
5
Initialise FOR - NEXT Loop (1 TO A)
Ш
фа
2 Timing Module Give “рес ready’’ message
2 Provide random delay to prevent antici-
pation
3 Set timing function by POKEing 255 into
the FRAMES addresses
4 Give signal
5 Walt for key to be pressed
6 Calculate reaction time. Allow for
computing time
7 Store result as B(A)
8 Add B(A) to X
9 Repeat 1-8, A times
3 Output Module = 1 Calculate average reaction time
Print average time
The timing module could be coded, run and tested as follows:
Timing Module Program Listing
1 REM REACT CORE FROGRAM
120 PRINT "-ON YOUR MARKZ-"
170 PAUSE 75
120 CL
190 PRINT “<GET SET?"
200 FOF L=0 TO END #35006
210 NEXT L
220 БОКЕ 16436:2955
230 PORE 1564373295
240 PRINT АТ 10510; "*Güx«"
250 IF ІМКЕҮ% ="" THEN GOTO 250
260 LET T=(255- PEEK 164362/50-4
(256%(259- PEEK 1649372) /50-0. 12
270 PRINT “REACTION TIME ";T;"
SECONDS"
Spectrum users should note the problem with INKEY$, and the fact
that we cannot use PAUSE @ since the PAUSE instruction uses
361
FRAMES also. The solution is to use the ENTER key as the key to be
pressed. Change line 250 to INPUT A$. As long as only the ENTER
key is used, this works. Change .12 to .03 (the time allowed for
computing) in line because of the faster response of the Spectrum.
When satisfied that the timing module works, we go on to code in the
rest of the program, editing any changed lines. (Only 260, since we
kept the same numbering.) You would have to change line numbers in
developing the program, unless you coded your program accurately
with line numbers before keying anything in.
For the Spectrum, modifications are required in the following lines:
200 FOR L = 0 TO RND * 1000
220 РОКЕ 23673, 255
230 POKE 23672, 255
260 LET T = (256 * (255 - PEEK 23673))/50
+ (255 - PEEK 23672)/50 - .03
If there are problems with the INKEY$ operation on the Spectrum (as
we noted earlier, it doesn't always work), the program should be
modified to:
1) Instruct the user to hold his finger over, then press the ENTER
key (lines 60 and 70).
i) Change line 250 to read INPUT A$. The null string will then be
entered when ENTER is pressed and the program will go to the
next line, to derive the reaction time.
Users in the U.S. must replace the 50 which appears twice in line 260,
by 60 to get an accurate timing result.
Spectrum users can use the DEF FN, FN functions for timing. See
the Sinclair Spectrum manual, Chapter 18, for a good description of
this method.
362
Flowchart “ВЕАСТ”
PRINT
INSITRUC-
TIONS
INPUT
TESTS
REQUIRED
SET ARRAY
B (A)
363
|
SET
TIMING
VARIABLES
ADD TIME
TO X
364
Program listing
S REM "REACT"
10 PRINT “REACTION TEST"
zü PRINT "à3xcx3*3 3€ 33 9€"
30 PRINT
40 FRINT "THE SCREEN WILL SHOW
ñ пи GET ZET "utu "
SO PRINT “MESSAGE. PLACE A FING
ER OVER"
60 PRINT "THE ""R "" KEY. WH
EN xGÜx* AFFPEARS"
70 PRINT "FRESS Е. EACH REACTIO
N TIME AND"
SO PRINT "THE AVERAGE WILL EE
DISFLAYELD"
70 PALISE 200
100 FRINT »s "ENTER NUMBER OF TE
STS REQUIRED"
110 LET X=0
120 INFUT A
130 DIM ECA)
140 PRINT
142 FEM
xxTEZT LOOP
150 Fok N-1 Tü A
140 FEINT "-ON YOUR MARKS-"
170 PAUSE 75
120 CLE
190 PRINT "GET SET?"
200 FOR L=0 TO ЕМО #500
210 NEXT L
215 КЕМ
+*5ЕТ TIMER EBYTES**
220 РОКЕ 1643732559
230 РОКЕ 16426%255
240 PRINT АТ 10310: "*G0%"
250 IF INKEY$ ="" THEN GOTO 220
260 LET Е(М2-(256%(255- РЕЕК 16
437) )/50+(255- PEEK 164362 /50-0.
14
270 PRINT "REACTION TIME ":ECN2
s" SECONDS"
280 LET X=X+E(N)
290 PRINT “PRESS NEWLINE/ENTEF
TO CONTINUE"
300 INPUT АФ
310 CLS
320 NEXT М
329 REM
*##ENDLOOP ++
230 PRINT
340 PRINT "AVERAGE TIME WAS "FX
/A;" SECS"
350 STOP
360 REM жЖЕМПжж
365
Comments: The use of an array (B(A)) gives us the flexibility to add
further manipulations (full printout or standard deviation, for
example) if we wished, by adding a further module to the program.
We could use the same principle to time other processes. The
accuracy of the allowance for the delay due to computing time becomes
less important as the time being measured increases. To derive a stop-
watch program (timing less than 65535/50 secs — about 21 minutes in
the U.K.) we would need a start and stop routine, built around the
POKE and PEEK lines. Write such a program. Notice how the
program is set so that the computer waits until a key is pressed in line
250. Remember we cannot use PAUSE in the form of PAUSE 40000
(ZX81) or PAUSE 0 (Spectrum) since that uses the FRAMES system
variables also, and would reset the timer.
2. “BINGO”
Problem: In the game of BINGO the caller shouts out the numbers
between 1 and 99 in a random order and each player has a card with a
set of numbers (say 15) in this range. The cards for each player contain
different sets of numbers. The winner of the game is the player whose
list of numbers is called first.
The program should play the game for up to four players and check
the validity of the winning player's card.
Outline Procedure: Modules are required as follows:
1 Set up game 2 Play game 3 Result of game
Procedure will be as follows:
Write preliminary instructions
Set up caller’s numbers
Set up players’ numbers
Display players’ numbers
Display caller’s numbers (one at a
time)
МЮ = к. ке e
— +> GO N н
2.2 Allow interruption by player
3.1 Display players’ numbers
3.2 Display numbers called
3.3 Check winning card
1.1 These are the instructions needed to start the game. At each stage
in the program it is essential to give clear directions to the user on
how to proceed.
1.2 ‘The caller's numbers require a random list of the integers 1 to 99
(each number occurring only once) which will be put in array
А(99).
366
1.3
The players` cards require 4 sets (cards) of 15 random integers in
the range 1 to 99 (i.e. different numbers). The cards should have
an ordered list of numbers and each list is a different set of
numbers. These will be put into arrays O(15), R(15), S(15) and
T(15).
Display the players’ cards on the screen and allow time for the
players to take down the numbers.
Display the caller’s numbers one at a time on the screen in large
form.
Allow the display to be interrupted when a player calls ‘house’
(i.e. thinks that all the numbers on his card have been displayed).
Repeats 1.4 for players to check their numbers.
The numbers called (i.e. those actually displayed in 2.1) are
sorted into numerical order (and put into array P(99) which
contains between 15 and 99 numbers) and displayed on screen.
The ‘winning’ card is selected and the numbers on this card are
put into the array V(15). These numbers are then compared with
the numbers called [in P(99)] to check that they are correct.
Algorithm Description
1.1
This section gives the minimum instructions required to play.
You may want to key in fuller details of the game of BINGO.
(Lines 10 to 110 in program).
1.2 Set up caller's numbers
Flowchart:
INITIALISE
ARRAY
This routine starts at line 120, clearing the screen and going into fast
mode on the ZX81 for the calculation. The above routine is contained
within the caller's numbers subroutine (lines 2500 to 2590), but note
this could be a subprogram sequence as part of the main program as it
Is only executed once.
1.3 Setting up (the BINGO cards)
Flowchart:
DIMENSION
ARRAYS
FOR EACH
NUMBER
ALREADY
CHOSEN
368
FOR
EACH
CARD
FOR 15
NUMBERS
LET Y = @
GOSUB
SORT
GOSUB
ARRAY
CHOICE
In the program this routine begins at line 320. Note array P(99), which
is used in the sorting routine (although containing only 15 numbers)
and is then used again later for the caller’s numbers.
Lines 480 - 540 carry out the selection of the 15 random numbers.
Subroutine 3000 — 3170 is the sorting routine which is the SHELL
SORT given in Section T. (A fast sort is needed as at a later stage we
are sorting nearly 100 numbers.)
Subroutine 3500 — 3560 puts the numbers into the appropriate
array.
1.4 This subroutine (lines 1600 - 1650) displays the numbers on the
cards in a tabular form.
2.1/2.2 Display caller’s numbers and interrupt if ‘House’ is called
оо O2
М mi
З.А
This subroutine takes numbers generated апа (in FAST mode оп
the ZX81) displays them 16 times their normal size and places
them in an array P. Variable Z counts the number of numbers
called. At the end of this subroutine the numbers called have
been put into the array P (which will contain Z numbers).
This repeats step 1.4.
This routine (lines 960 — 1070) calls a sort subroutine at line 3000
which sorts the list P (Z) into numerical order and prints them out
on the screen.
This subroutine (lines 4000 — 4260) has two parts.
(1) Select the ‘winning’ card and arrange for the ‘winning’ list
of numbers to be put in the array V(15) (lines 4000 - 4120)
(2) Check the numbers on the ‘winning’ card. It is necessary to
search the ordered list P containing Z numbers for the
numbers in the ordered list V containing 15 numbers. If any
number is missing the card is not complete. If all numbers
are present then CONGRATULATIONS is printed.
The quickest search method is as follows:
Search for V(1) in list P until it is found, say P(12).
Search for V(2) in list P beginning at P(13) etc.
The search will end as soon as a number in list V is not in list P
but will continue for all 15 numbers in list V if they appear in list
P. The flowchart for this search is as given below:
370
COUNTER FOR
LIST P
N=] COUNTER FOR
N>15 LIST ү
PRI
V(N)
CORRECT
LET
M = M+]
CHECKS IF
NUMBERS IN
LIST.P
FINISHED
COMPLETE
RETURN
E 2 TO GAME
PRINT
СОМСААТ-
ULATIONS
STOP
371
Data Table
The following variables are used:
Q(15), R(15), S(15), T(15) are the arrays containing the players
numbers.
A(99) is the array containing the numbers for the caller.
P(99) is the array containing the numbers actually called, and is also
used as a temporary storage in setting up the players’ numbers and in
the sorting routine.
X is a random number between 1 and 99.
Z is a counter for numbers called.
Y is the number of elements present in an array to be sorted.
V(15) is array containing ‘winning’ list of numbers.
B$(99,2) is an array containing the string values corresponding to the
elements in P(99).
C is the character code of second character in element of array B$.
D is the character code of first character in element of array B$.
M is the counter for array P in the ‘check numbers’ section.
Comments: If you wish to play with your own BINGO cards and let the
computer be the caller only, then you can delete modules of the
program as follows:
1.3 Set up players’ numbers
1.4 Display players' numbers
3.1 Display players’ numbers
These latter two modules are the same subroutine. You could also
revise the program and include, as an option in the user instructions
routine at the beginning, the choice of the two different modes of play.
Spectrum modifications:
Delete Lines 290 and 585.
Change Line 660 to 660 PAUSE 0
Delete Line 830
Change line 800 to 800 FOR F = 1 TO 400
Edit line 810, renumber as line 805, to read 805 IF INKEYS$«»'' ”’
THEN GOTO 830
New line 810 NEXT F
Note: This sets up a FOR - NEXT loop to contain the reading of
INKEYS, to make this operation of checking to see if someone's bingo
card is full more reliable. The delay of a 1 TO 400 loop is about two
seconds, the same as the PAUSE in the original program.
Edit line 835, renumber as line 830, to read 830 CLS
Delete line 835
Change line 980 to PAUSE 0
Delete line 1005
Delete line 1025
Delete line 5010
372
Change line 5070 to 5070 LET E = PEEK (15360 +8*C +R)
Change line 5200 to 5200 LET Е = PEEK (15360 +8*D +R)
Flowchart ‘BINGO’
START
PRINT
INSTRUCT-
IONS
PAUSE
PRINT
NUMBERS
CALLED
PAUSE
STOP
SELECT
NUMBERS
GOSUB
BIG PRINT
BINGO
CALLED
212
Program Listing
2 GEM SS NGO”
10 REM RRR KR ХХХ OY HERE
%1, 36% INSTRUCTIONS %
XX 3e XXE EE ЖЖЖ ЗРЗЕ ЭЗЕ
20 PRINT TAB 10; "BINGO": TAE :
ох ыы
30 PRINT |+ É "SOUR EINGO CARDS A
RE PRODUCED"
40. PRINT 99 "А5 THE LISTS "" WQ
ни 4 ип A пи ' ы" Өт ТЕГ] AND "H" n
T пи и
20 PRINT »+"THEY ARE СОСОРТЕП 71)
А PRINTER" ++, "TF CONNECTED, OTHE
RWISE YOU MUST"
60 PRINT so "NOTE DOWN YOUR CHO
SEN LIST WHEN"
70 PRINT |+ + "THEY АРРЕАР, NOTE T
HE LETTER ALSO”
ШО PRINT »% “WHEN YOL ARE READY
FRESS ANY KEY"
70 PRINT || "TO START. THERE WIL
L BE A DELAY"
100 PRINT |, "WHILST THE NUMBERS
ARE SET UP,"
110 IF INKEY$ ="" THEN GOTO 110
120 CLS
200 RAND
290 FAST
200 REM 33433 C HHH Ж
*1; Z«*SET UP CALLERS x
* NUMEE Fs: x
Хх ЖҰ Ж
210 DOSJE 2500
320 REM 3J4333X34X3 3 € 3€ (XC C969 3 3 X.
*1.cXSET UP PLAYERS *
* NUMBERS *
3X 3C 3C 3C3C 33€ 3E 3€ 3E KH 553
420 DIM acis)
430 DIM Есі)
440 DIM 5(1©®)
450 DIM Tc183
4640 DIM P(9?93
470 ЕСЕ W=1 TO 4
430 FOR J=1 TO 15
490 LET X= INT (7
500 FOR Isi TO J-1
510 IF XzsP(I2 THEN GOTO 490
220 NEXT I
S90 LET PGJ»zX
540 NEXT .
550 LET Y=15
ESO GÜSLE 3000
570 DOSIJE 3500
280 NEXT U
seo SLOW
S70 PRINT
600 FRINT
610 REM XXX 33333 33 M EE 364396
#1, 48 DISPLAY PLAYERS ж
ж NLIMBES ж
ХХХ
DOSJE 1600
DG.
э
LI e
374
& 30
640
850
REM **L IST COPIED IF жж
жж PRINTER жж
COPY
PRINT »» "PRESS ANY KEY TO F
ROCEED"
EGO
670
650
THE
EPO
700
IF INKEY$ ="" THEN GOTO 660
DLE
PRINT "THE CALLER WILL GIVE
NUMEERS ONE AT A TIME"
FRINT
PRINT "WHEN YOUR CARD 15 cU
MPLETE PRESSANY KEY WHEN NUMBER
IS ON SCREEN"
710
720
CEED"
730
732
740
745
720
755
760
PRINT
PRINT “PRESS ANY KEY TO РЕС)
IF ІМКЕҮФ ="" THEN GOTO 730
CLS
REM 3333 3 3 X X X € ЗЕ M
+2. 1% PRINT OUT CALLS x
HHH HH HHH EE EE EE HE
LET Z=1
DIM Beers, 2)
CLS
PRINT " PRESS ANY SEY WHEN
YOUR CARD IS COMPLETE”
770
750
790
793
200
210
=O
я Е
CS du
220
S20
[жа есі =
240
S50
EINE ЖЫ
S40
270
2120)
890
200
910
920
730
935
940
745
250
ЕКПЕ N=Z TÜ 99
Güzim] Sooo
LET FCN) =ACND
PAL'SE 200
REM 33 3 3 9€ 303€ 9€ 3€ 9€ 30 3€ 3E 3E 3E CE CE E
#2. Z2XPLAYER INTERRUPT ж
HH 3CCC JC 3C Хы
IF INKEY$ <> "" THEN GOTO &
LET Z=Z+1
NEXT N
LW
| L LZ
FOR N=1 TO 10
PRINT ТАБ N:"Z«*BINGUÜUS-ZXEIN
NEXT N
PRINT Өз “CHECK YOUR CARDS"
REM 3C 3C 36 36 3: 3€ 3€ 9€ 9€ C Хы Ж
яз, 1*DISFLAY PLAYERS ж
* NLIM RER © %
ХХХ
РАЦЕ 100
LET Y=Z
PRINT “YOUR NUMBERS WERE"
PEINT
REM X33534 3333333 M EE SE ARERR
ЖРБІМТ QUT CARE NUMBERS +
GIJE 1600
FEM
FEM жж Хы 3E 9C ы Ж
X. ZXDISPLAY NUMBERS ж
* CALLED *
Y X 3C 3€ 3C CC 555555553553
375
260 PRINT “PRESS ANY X БҰ TO GET
LIST ОЕ", "THE NUMBERS CALLED. "
1270 PRINT "THERE WILL ре А SHOP:
T DELAY FOR SORTING, "
9780 IF INKEYS ="" THEN GOTO F20
we cl ©
1008 FART
1010 pne zi oc
1020 ELS
TOFS SLOW
1030 PRINT "CALLERS LIST"
1040 PRINT
1050 FOR Nel TO Z
1060 PRINT РМ" "3
1070 NEXT N
1050 PRINT
LOSE REM HREM ERR EER EE HEH REALE EH
#3. JW CHECK WINNING X
ж MARI *
XE 3 XXX XC ЖЖ
1070 GÜSLUE 4000
1100 LET 2=2+1
1110 PRINT ++ "DO YOU WISH TO CON
TINUE THE GAME? CY/N3"
1420 INFET CS
1120 IF C#="N" THEN STOP
1140 IF Ce="¥" THEN GOTO 755
4450 PRINT "INPUT Y OR N ОМЕР.
FASE"
1160 GOTO 1120
11920 REM J3XX33 0 (4 0 Хы
ж END PROGRAM x
X XC 34 АЕ 3E EXC OE EXE EE EEK at
1200 STOF
1210 КЕМ
| EDO REM жұ АЖ
x SURO TT NES ж
ХЕҰ XE COE Ж
15920 КЕМ
AOG Б ЕМ ж EXE CE EE EK EH
ЖЖСӘМБЕЕПШТІМЕ TO PRINT ж
AOUT PLAYERS CARLS +
HH HHH HE HE EE EE 6
“410 PRINT "Ga": TAB 6: "8S"? ТАР і
ев: TAB Ter *t*
4620 FOR ті TO 45
2420 PRI NT Gc.5; TAE &G:RCZo0: ТАЕ
iz:m620: TAB Ler Сш
1440 NEXT 4
TESO RETURN
1660 REM жж МОЛ жж
Хх ЖЖЖ ы
2470 REM
SIO) БЕМ eM HE EH
#*#¥5UCREOUTINE TO SET жж
XXCALLERS NUMEBERZ Xx
FEE ЖЖ EEE
того DIM ACHD)
2240 FOR Net TO PP
376
ore as.
2520
2570
2580
2590
29850
S000
2010
32030
2040
S080
S060
3070
TOSO
S070
3100
3110
2120
2120
2140
3150
21680
2190
3470
2500
3510
3220
3530
t ul el
3540
3550
3&0
3870
4000
4010
4020
зуу
IF ACX) <> 0 THEN SOTO 2550
LET АсХ>=
NEXT N
ЕЕТМЕМ
LET X= INT (99% RND 2-1
М
REM жж ENDHI X%
X33 ЕЕЕ HR KEKE XXE CX
КЕМ 303 3 9 0 € CE HHH HH Ж
X*SORT SUBROUTINE жж
ж Ж ХХ
LET S=
LET S= INT (S/2)
IF Š >= 1 THEN GOTO 2050
GOTO 3170
FOR К=1 TO Š
FOR AsK TO Y-S STEP K
LET E=A
LET TsP(A«2)
IF T >= РСВ) THEN GOTO 2130
г
(ЕТ Ве-В-<
IF В >= 1 THEN GOTO 3090
LET P(B+S)=T
GOTO 23010
RETURN
REM жж ENDSUE +
HHH HH RIK REE ЕЕ ЭЕ ЗЕ KRK
REM
fet LF ХХХ EE 3C YE
S## 5G ROUTINE FoR КОМБ»
23 NUMBER ARRAYS жж
JC X- 3€ 3C 3€ 3C 3€ 263 3 3E ЭРЭР 36 3E 3E HEH EHH EE
1 70:12
2/7 BL
IF Ше1 THEN LET ос) =Р CJ)
TF Uz2 THEN LET--R(Jy=P (J)
IF Нез THEN LET SCAOD PCI
IF l4 THEN LET Tc PG)
RETURN
REM жж ENDSUE жж
He KE SEE FEE EEE EEE EE E
REM
REMO ж ЖҰ ы
ЖЖСШИБЕПИТІМЕ TO CHECK ae
HX RESULTS жж
363 4C 3C 3E JC XC 3C 3€ 0E ыж
PRINT
[REM 3 Xx 3C Ж ee OMO
#3. 3. IX SELECT WINNING ж
ж CART є
HHH X3 HHH HH HH MOORE MOYO
PRINT "ТҮЗЕ WINNING CARD (È
T3 it
377
4020 INFUT АФ
£040 IF AS <> "QU AND AS <> "m"
AND АФ <> "S" AND AS <> "T" THEN
GOTO 4020
4050 CLS
4060 DIM Vct&)
4070 FOF N=1 TO 1%
4080 IF Ag="h" THEN LET V(N)=m (N
3
4090 IF АФ=" 8" THEN LET VCNI=SRCN
3
4100 IF Ag="5" THEN LET V(N)=S (N
E
4110 IF A$z"T" THEN LET V(N)3=T (N
)
4120 NEXT N
4195 REM хх 3XX XXX XC XXE
#3, 2. ZXCHECK NUMBERS ж
522222552222 52222 EY
4130 LET М1
4140 FoR Nzi To 15
4150 IF V(N)=F(M) THEN PRINT VON
Jj?" QURRECT”
4160 IF VCNI=SFP CM) THEN GOTO 4200
4170 LET M=M+1
4120 IF M=Z+1 THEN GOTO 4220
4170 GOTO 4150
4200 NEXT М
4210 GOTO 4245
4220 PRINT “#CARD "FAG?" NOT COM
PLETED»"
4230 PRINT МОМ)?" NOT CALLED"
42552 REM
XGÜTO RETURN TO CONTINUE
4240 GOTO 4260
4245 PRINT »» TAB 47" жж CONGRAT
ULATIONS жж "; TAE 45 "%%%%%%%%%%
%%%%%%%%%"... "GAME ENDED. USE RUN
TO RESTART"
4250 REM
жж GOTO PROGRAM END жж
4255 GOTO 1200
4260 RETURN
4270 КЕМ жж ЕМПЕМЕ жж
JC OC XC 3C JEFE AE 3C 3C ЭЕ ЭЕ ЭЕ ЭЕ ЗЕ ЭЕ ЭЕ ЭЕ ЭЕ ЭЕ ЭЕ ЭЕ XE
4900 FEM
SOOO REM ххх x * x X X HEH Хы HE
*#*#SUBROUTINE GIG PFLOT**
ee Ж
2010 FAST
2020 LET Е%(Мо- STR ACN?
5030 LET C= CODE БФ(М2(1 TO 1)
5040 IF LEN ЕФ‹М)© 7 THEN Goto 50
eo
378
5050
=060
5070
5020
2090
2100
5110
214
2160
2170
5150
2190
=
200
5216
=. » а
` а а
2220
“2840
s dad
2250
т270
есес
5290
“Ооо
AGIO
A020
GOTS
z QAQ
ë GS
ё 872 С )
5070
3. “REF. INDEX"
Problem: In a laboratory experiment with a spectrometer, a series of
measurements are made of the prism angle A and the angle of
minimum deviation D for various prisms. The refractive index of each
LET D= CODE E$CN» (2 TO 2)
FOR R-O TO 7
LET E= PEEK (7680+8xC+R)
БЕТ W= 125
FOR б=0 TO 7
IF E<W THEN GOTO 5150
PRINT AT 2#R+5. 2#G+17 E.
PRINT AT 2ЖЕғ5.2ж041;"
LET ESE-MW
ЭТО 6:2?О
PRINT АТ 2#®+5,2=5+1;
PRINT АТ 2#К+6,2#%0+1;" "
LET W=W/2
МЕХТ б
IF LEN B$%(N)<2 THEN GOTO 20
LET F= PEEK (768048*D4R)
FUR Н=0 TO 7
IF F«W THEN GOTO 5280
PEINT АТ 2жкесутжнеіс: "ШЕ
PRINT АТ ZX*R-*53ZXH-915; ш.
LET F=F-W
UTO 4000
PRI! Ba AT SHE PEEL A U Т
PRINT АТ ZAR ty Zapia" u
LET A J=1J / 2
NEXT H
NEXT R
SLOW
RETURN
REM ж ENDZLUE X%
ж MEER 0€ 3C XC GE
REM
REM жж END PROGRAM LIST*x*
HHH NEE HEH HAE EE EE EE
is then determined using the formula:
We require a table of results and an average of the refractive index
results for each prism. Six prisms and four measurements for each
Sin (A + D) = Sin (A)
2 2
prism are to be allowed for.
Research the problem: Since we are using up to six prisms and each
one can have four readings it is convenient to use nested loops and two-
dimensional arrays to store the input. In this way A(3,4) can, for
example, represent the third prism, fourth reading of prism angle. We
will use lists to refer to the prisms and the quantities associated with the
379
prisms, so that, for example, Z(3) can represent the average refractive
index of the third prism.
Angles will be input in degrees. Since the formula for the calculation
requires the use of the Sine function SIN, we will need to convert to
radians. This will have to be done before the refractive index is
calculated. We can provide a simple input check in a subroutine. Zero
entries in the input loops will signify end of prisms or end of readings.
Outline Procedure:
1 Input: Data
2 Calculate: Refractive indices and averages
3 Output: Results in suitable tabular form
Detailed Procedure:
Dimension Arrays and Lists
FOR each Prism (1 to 6)
Set Z as zero
Input Prism number
If Prism = 0, GOTO 3.1
FOR each Reading (1 to 4)
Input Prism Angle
If Angle = 0, GOTO NEXT Prism
Input Minimum Deviation
Convert angle to radians
Convert minimum deviation to radians
Calculate Refractive Index
Round to 3 decimal places
Add Refractive Index to Z
NEXT Reading
Average R.I.=Z divided by number of
readings
Let Average R.I. = Z(N)
NEXT Prism
Print Headings
FOR Each Prism
FOR Each Reading
If Reading not 0, print Prism, Number,
Angle, Minimum Deviation, Refractive Index
NEXT Reading
NEXT Prism
Print Headings
FOR Each Prism
Print Prism Number, Refractive Index
NEXT Prism
Input null string if error, C if correct
1 Input
2 Processing
NO NO NO NO ND DN N = = ка = Re eS = ке кә
SOD Q + OO NK СО @ +I O OF > WO NH =
3 Output
оо шо бо бо м м
+ O39 м = O оо
+ 52 GO OO GO OO OO
— ка (O Со SIO 0
=<
4 Correct
380
Error 4.2 Return
Subroutine
Note:
Subroutine called after each input. All entries can be re-input if
Incorrect. See program listing.
Data Table
Prism number
A(6,4) Four Angles of measurement for each of 6 prisms
D(6,4) Minimum Deviations, for each value of A(6,4)
N(6,4) Results of refractive index calculation for each experiment,
derived from the values stored in arrays A and D
Variable to store totals of minimum deviations.
Average refractive index for each prism, from the average of
the four values stored in array N.
Used as loop variables for input
Used as loop variables for printout
Used as input for error check subroutine.
Null string if incorrect, ‘‘C’’ if correct.
START
DIMENSION
Flowchart “REF. INDEX
ARRAYS
OUTPUT
RESULTS
STOP
INPUT
PRISM
NUMBER
381
INPU
CORRECT
CONVERT
TO RADIANS
CALCULATE
R.I., ADD
TO Z
es
No INPUT Yes PRISM
CORRECT =ø
No
M = ]
CALCULATE
AVERAGE
R.I, FOR
PRISM
382
Program Listing
= REM "REF. INDEX"
10 PRINT "**xREFEACTIVE INDEX3*
"soo “USING SPECTROMETER"
20 PRINT ss "ALLOWS UP TO & PRI
SMS AND 4 SETS OF READINGS FOR E
25 REM *-*AVGE REF. IND. AEEAY**
30 DIM Z¢4)
35 REM **FFISMS ARRAY **
40 DIM Fé)
45 REM ##*#FRISM ANGLE ARRAY *#*
50 DIM Ас 4)
59 REM ##*#MIN. DEV. ARRAY**
60 DIM П(6з49
ес REM ЖҰРЕҒ. IND. ARR AY**
70 DIM N(65 43
SO FEM жж ХЕ ЕЖ
85 REM **INFUT DATA LOOF#+*
90 FOR N=1 TO é
100 LET 2-0
110 PRINT "INPUT PRISM NUMBER» I
МРОТ 0", "ТО FINISH"
120 INFUT P (N)
130 PRINT "PRISM NUMBER ";P (N)
140 GOSLIB 700
150 IF A$ <> "C" THEN GOTO 110
160 IF F'(N)=O THEN GOTO 500
165% REM J3HuUdciads €x ХЫ +
X*START READINGS 100Ржж
170 FüR M=1 TO 4
180 PRINT "INFUT FRIZM ANGLE IN
DEGREES: INFUT Ó TO FINISH"
190 INFUT АСМ» M) |
200 PRINT "ANGLE OF PRISM "АСМ
M)
710 GŪSIE 700
220 IF A$ <> "C" THEN GOTO 180
220 IF ACNsM)=0 THEN GOTO 410
240 PRINT “INPUT MIN. DEV. IN DE
GREES"
250 INFUT DCN: М)
260 PRINT "MIN. DEV. ";D(Ns M)
270 GOSUE 700
280 IF А% <> "C" ТНЕМ БОТП 180
290 REM жжСПМУЕЕТ DEGREES Тож
xxFEADIANZ жж
300 LET А=АсМ, М) + PI /180
310 LET D=DCNsM)* РІ /180
220 REM *#REFRACTIVE INDEXs*
230 LET М(МЭМо-( SIN ¢¢CAtD9/23 3
/ SIN (6/2)
340 LET МСМ. М) = INT CLOOO#NCNSM
2%, 33/1000
250 LET Z=Z+N(N; М)
360 NEXT М
270 REM ##END READINGS LOOP жж
ХХХ Жы
330 REM
390 REM жжАУЕРАСЕ TO 2 DEC. ++
++ PLACES ++
383
400 REM
410 LET Z=Z/(M-13
420 LET 7(Мо- INT (100%7-,52/10
Ü
430 NEXT N
440 REM
450 REM *#*ЕМП INFUT LOOP ++
460 REM >> X X3 (€ 3€
470 REM
450 REM 34333 3 3 9 9 3€ 3€ 3€ 9€ 9€ 9€ 3€ 9€ 9€ 3€ 3€ 9€
470 REM ** PRINT CUT жж
4952 КЕМ
500 РЕІМТ "РЕІЕМ ж ANGLE ж MIN.
DEV ж ЕЕ, ІМ. ЖЖЖ 33 3333
JC 33 3€ 9€ 363€ 3€ 3C ыы.
510 FOR Y=1 TO N-i
520 FOR X=1 Tü 4
S30 IF AcY¥YsX)=0 THEN GOTO 550
540 PRINT FCY): TAB &;"+*+ "АСУ,
Xd; TAE 143 "ж "#D(Y Ís X); ТАЕ 243"
ж "FNCYs X)
550 NEXT X
S560 NEXT Y
570 PRINT "4333 3 3 3 3€ € 3€ X 39€ 3€ 3€ 3€ 3€ 3€
XXX 3333€ (X!
S80 FRINT
$590 PRINT »» "AVERAGE REFRACTIVE
INDICES"
&OQ PRINT U33333 3433383333 HEHE
хын
610 PRINT "РЕТЕМ"» "REF. IND."
620 FOF X=1 TO N-i
630 PRINT FCX) ZCX)
640 NEXT X
650 PRINT
&&O PRINT "33 39 9:9 3€ 3€ 3€ 3 EH € € €
3C3t 39€ 9€ 3€ € 9€ 9€ 9€ 9€ 9€ "'
670 GOTO 770
6580 REM
690 REM 33333939 9 ) 9 9 HEHEHE HEHE
&9*5 КЕМ
700 REM **CORRECT ERRORS SLUEx-
710 PRINT
720 PRINT “INPUT C IF CORRECT:0
THERWISE":;"PREESZ NEWLINE"
730 INFUT A$
740 CLS
750 RETURN
760 FEM
жжЖЕМП SUBROLUTINE*
Ж ЖҰ CC
770 STOP
720 REM #* END жж
384
Sample Printout:
PRISM * ANGLE * MIN.DEV % RF.IN.
& k k k k k k k k k k k k k k k k k Kk k k K k k K k k K k R k k Ro R K
1 * 59.8 * 40.5 * 1,58
1 * 60,1 * 40.2 Ж-1.,223
2 “ 61.2 * 45.3 е T2327
2 "2 ж 45.1 “71.562
2 * 52.5 ы. 45.4 * 1.558
k k k k k k k k k k k k k k k k k K k k k k k k k k k k k K k k k k K k
AVERAGE REFRACTIVE INDICES
k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k
PRISM REF. IND.
I 1.54
2 1.586
* coe k k k k An n Je à An An ХХХХЕХЕХХХЖХХХХХхХЖҰХҰ« ХА xn x x x
Comments: Note the importance of a check subroutine in this type of
multiple-entry program. It gives the user the chance to verify that the
input data is correct. It might have been better to have written a
program to deal with any number of prisms and any number of
readings. Consider what changes this would make to the program.
There are many other physics experiments which may be treated in a
similar way. For example:
(1) The value of the gravitational constant 2. simple pendulum,
; ; l , | |
using the time period equation Т = 271 g for experiments with
pendula of various lengths 1 to determine the average value of g
resulting.
(п) The determination of the velocity of sound, using a resonance
tube to find the 1st and 2nd resonance lengths (L1 and L2
respectively) and using the equation V = 2f(L2 – L1), where
f = frequency of the sound, and V the velocity.
4. “SERIES”
Problem: We are asked to sum the series that gives us the value of e
raised to the power x. This is:
3 n
. © Ж x i
е шы жататы аа таты. ... for any value of x, with an accuracy
n!
of 1 part in 100,000 (i.e. 10-7, .00001).
385
Research the problem: This is the EXP function on your computer,
evaluated as a series. The resulting value of, e.g., е, will be
approximately the value of EXP 3 if you used it on the computer. ‘This
Is a convergent series, E value of ie term gets smaller. For example, if
we take x = 2, > от! Тел 1 = 2, whilst — 3 - Xi = 1.333... , At a certain
point, the effect of adding the value of another term is to increase the
sum by less than the accuracy we require. The summing is then
finished.
Procedure: This requires a procedure which allows any term in the
series to be calculated from the previous term. This is the basic
algorithm for summing many series.
At this stage we need to consider if it is a specific problem or whether
we could extend it to deal with other similar series-sum problems. It is
important to make this decision before the program is written as it is
often very time consuming to modify a program at a later stage. The
answer is yes. We can then restate the problem as: a program is
required which will sum a convergent series to any desired accuracy
(subject to the limitations of the computer's arithmetic), provided that
any term may be expressed as a function of the previous term, with the
information needed being the first term and the common ratio. The
common ratio is the equation that enables us to calculate any term
from the previous one.
For our problem: take the exponential series:
x^ ҳ?-!
S=] $K Peres PT
2! (n – 1)!
th
n term
In this series the first term is 1.
h n-1
The common ratio = X Ded The п" term is oD! and the
п-2 п-1 25 |
(n — 1)" term is — — The ratio is —— (асли = ——
(n — 2)! (п- 1)! xn-2 п- 1
We require an accuracy of one part in 100,000 (10-7). When the
effect of adding another term increases the sum by less than this, the
program should stop processing and output the result.
Outline Procedure:
1 Input necessary information
2 Sum series term by term
3 Compare sum with previous value
4 Print out result when sums differ by less than required value
Detailed Procedure:
1 Input 1.1 Common Ratio – may be easiest to have a re-
placeable line in program.
386
2 Sum
3 Comparison
4 Output
Results
Input
N) н ка ка
.2 First term - easily input
3 Accuracy - easily input
.4 Value of X - easily input
.l Initialisation - set 1st term equal to given
value which in turn is the sum of the series at
this stage.
2.2 Next term — may be calculated by multiplying
first term by common ratio.
2.3 Sum - may be calculated by adding this term
to previous sum
3.1 Compare this sum with previous value then
EITHER go to 4.1 if the difference is /ess than
that required or go back to 2.2 if difference is
more than that required.
4.1 Name of series
4.2 Accuracy
4.3 First term
4.4 Valueof X
4.5 Sum of series
4.6 Number of terms
Variables Table
Name of Series
Value of first term in series
Value of X
Accuracy required (difference between terms, such
that program terminates when difference smaller
than this).
Processing and Output
ii
N
51
5
51-5
TsT*X/(N - 1)
Value of current term being processed
Number of terms
Value of Sum of series of N - 1 terms.
Value of Sum of series to N terms.
Difference between the sums of the series to the Nth
and (N - 1)" terms, checked against value of D.
Calculates value of next term in series from current
term.
The common ratio is set in line 260. This line must be changed for
different series. Spectrum users could use the DEF FN instruction in
initialisation, and the FN instruction to evaluate the expression in line
260. Try this when you have familiarised yourself with this function.
387
Flowchart “SERIES
START
NEWSUM =
FIRST TERM
SUM =
NEWSUM
INCREMENT
NO. OF
TERMS
CALCULATE
NEXT TERM
VALUE
NEWSUM =
NEWSUM PLU
TERM
PRINT
RESULTS
10
ЕЕМ
Program listing
"SERIES"
20 PRINT " ж» SERIES жж "s333"
THIS PROGRAM SUMS ANY SERIES"
ЗО PRINT ss"WHICH IS CONVERGEN
T AND WHERE"
40 PRINT з» "АМҮ TERM MAY ЕЕ CA
LCULATED ҒЕОМ"› з» "THE PREVIOUS T
ERM"
50 PRINT »» "REPLACE LINE 260 ñ
5 APPROFRIATE"
60 PRINT ss "HIT A KEY TO START
65 REM ##FAUSE О FOR SPECTRUM
**IN LINE 70 жж
70 PALISE 40000
80 CLS
90 PRINT “INPUT МАМЕ OF SERIES
100 INPUT A$
110 PRINT “INPUT VALUE OF FIRST
TERM"
120 INPUT A
130 PRINT “INPUT VALUE OF X"
140 INPUT X
150 PRINT “INPUT ACCURACY REQUI
RED"
160 INPUT D
165 REM
170 REM **«FIRST TERM**
175 REM
180 LET T=ñ
185 REM
190 REM **NUMBER OF TERMS
195 REM
200 LET N71
205 REM
210 REM s*SLUM S:NEW SUM S1*
215 REM
220 LET S128
230 LET 5-51
235 REM
240 REM **xCALCULATE NEXT TERM*s
245 REM
250 LET N=N+i
255 REM **SPECTRUM USERS САМ жж
**#USE DEF FN HERE жж
260 LET T=T*X/(N-1)
265 FEM
270 REM **CALCULATE NEW SLIM*#*
275 REM
280 LET $1=S1+T
285 КЕМ
290 REM **COMPARE S AND S1s*
295 REM
300 IF ABS (S1-S)>D THEN GOTO 2
30
310
CLS
315 REM **OUTPUT RESLILTS3*
320 PRINT "SUM OF “;А%:" SERIES
389
230 PRINT "3333993 93 99 3 3€ € 96€
3t 3€ 3C 36 3€ 3€ аа ы
340 PRINT "TO AN ACCURACY OF ";
D
350 PRINT
360 PRINT "FIRST TERM=";A; ТАР
Оз "VALUE OF X=";
370 PRINT
380 PRINT "SUM "513" МО. OF TE
RMS "+N
390 STOF
400 REM **END PROGRAM*+*
Sample printout:
SUM OF EXPONENTIAL SERIES
Yes e fe de k kok k k k kf kok koko КККК ККК Fe de He КККК КК
TO AN ACCURACY OF .00001
FIRST TERM=1
VALUE OF X=1
SUM 2.7182815 NO. OF TERMS 19
Comment: Typical examples of other series that could be summed using
the same program are given below:
S=1+x+x°+x'+..... С... Po
2 4 2n
Cos x= 1-57 +7) TT (- "Quy for all x
x? х? е yx2n+1
Sin х=х- 9; t 5 sass Le) Tno Dj e sis
Sel-xtx-x-4...... if x«1
Now consider how you might improve upon this program. Ideally this
should have been considered at the planning stage and not after coding.
We should perhaps include a subroutine to correct the sum to the
appropriate number of decimal places or routines to enable the user to
check that input data is correct. We could LPRINT directly to the
printer for our hard copy printout, to avoid using COPY.
9. “GRAPH”
Problem: 'To produce a useful hard-copy graph of various functions
(Y 2 function X) in the positive quadrant (X and Y positive), with titles
and scales included.
Research the problem: The program must allow a variety of
functions to be plotted. Thus there must be an input or a line of the
program to be altered, according to the function which is to be plotted.
Titles are to be printed, as are scale values. Hence we need to know
the area of the screen in which we are to plot, and define the plotting
390
routine so that it keeps within this area. Indications of the scales should
be visible on the plot screen, to enable approximate values to be read
off. This will require inputs.
Scale factors must be established so that the points to be plotted are
within the defined area and good use is made of the available area, so
that the graph is not cramped. The capacity to calculate the values of
the dependent variable Y for a chosen range of X will be needed.
Alterations of the values of X, so that the derived range of Y may be
altered if necessary, should be possible within the program.
As in all graphing programs, some degree of inspection and choice is
required. In this case the requirement for scales to be printed requires
the input of suitable intervals to make the graph functional.
The program will hence require the following modules:
1 Input and calculation of function to be plotted. Revision of X
values and re-calculation if required.
2 Input of X, Y scale values and calculation of scale factors.
Printing of graph surround, titles, scale values.
3 Plotting of function.
Outline procedure:
Module1: 1 Input: Function to be calculated.
Values of X to define range of X
required.
2 Calculation: Calculate and store in array values of
Y.
Find maximum and minimum values
of Y.
Scale factor for X axis.
3 Output: Maximum and minimum values of Y
for specified range of X.
4 Repeat 1 – 3 if required. User input to decide if required.
Module 2: 1 Input: Low and High X, Y values.
Scale values for X and Y axis divisions.
X, Y axis titles.
Graph titles.
2 Calculate: Scale factor for Y.
3 Output: Print titles, scale values, major scale
intervals.
Module3: 1 Input: Values of Y stored in array.
2 Calculate: X, Y plot values, in accordance with
scale factors.
3 Output: Plot of function in specified area of
screen.
Detailed Procedure
The descriptive algorithm (with user notes) for obtaining the best
possible plot within defined scales is as follows. The user must be
presented with the information required to make decisions as to
suitable values for the X and Y axis scales.
1 Define range of values of X for which values of Y are to be
obtained.
1.1 Input minimum value of X (MINX).
1.2 Input maximum value of X (MX).
Note: Values of X should be chosen such that the scale divisions
correspond to values of X that will fit the defined purpose of the graph
(range of X required). Thus the range of X would be chosen to suit the
major scale divisions of the ‘graph paper’ drawn by the program. We
would choose X to be plotted on a scale running from 0 to 5, to give
scale divisions of: |
0 1 2 3 4 5
along the X axis, even though we were primarily interested in the plot
of Y with X in the range, say, 0.5 to 3.9, adapting the X values to the
constraints of the graph scales drawn on the screen. (See the sample
printout for these.) Similarly, we might choose X axis scale values of
0.4 0.5 0.6 0.7 0.8 0.9
to fit within the constraints of the display, even when the prime сопсегп
was the plot of Y when X runs from 0.5 to 7.9.
1.3 The scale factor for X (DX) to be used in the calculation
loop to derive values of Y is then (Number of points to be
plotted оп X axis/(Maximum X - Minimum X)). DX =
50 (МХ-МІМХ) for the ZX81 and 200 (МХ- MINX)
for the Spectrum.
2 Calculate values of Y for each value of X.
2.1 Set X equal to minimum value of X (MINX). Start
calculation loop.
2.2 FOR each plot division on X axis (1 to 50 on ZX81, 1 to 200
on Spectrum).
2.3 Calculate Y = (Function of X). Use VAL to calculate value
of function input as string.
2.4 Store value in array N (N(F) = Y).
2.5 Increment X for next plot point (X = X + DX).
2.6 NEXT plot point on X axis. End of calculation loop.
Note: The values of Y are now stored in array N. We now require to
know the minimum and maximum values of Y that have been
produced by the calculation. We must search the array N for these
values.
392
3 Search Array for Maximum and Minimum values of Y.
3.1 Set Maximum value and Minimum value variables
(MAXY and MINY) equal to first Array element.
(MINY = N(1),MAXY = N(1)). Start search loop.
3.2 FOR each element in array (N(2) to N(End)).
3.3 If array value is less than minimum value variable (М(Е)<
MINY) then set minimum Y variable equal to array
element (MINY = N(F)).
3.4 If array value more than maximum value variable, set this
variable equal to array element (MAXY = N(F)).
.) NEXT array element.
Inspect Range of Y.
1 Print maximum, minimum Y values (МАХҮ,МІМҮ).
2 Present menu choice of: (i) Recalculating for a different
range of X. Program returns
to 1.1 if selected.
(11) Choosing Y axis values.
Note: The user must now select the scale values for a range of Y such
that all values of Y are within the range chosen and maximum vertical
spread of plot points is achieved to avoid a cramped plot. This latter is
the same decision as was made for the X axis values. A suitable scale
must be chosen to conform with the scale divisions presented on the
screen. The Y axis has three scale sections, requiring four scale values
at the vertical divisions of the graph.
If MINY were 0.12 and MAXY were 3.6 for a given range of X, for
example, we might choose to set the minimum scale value for Y as 0,
and the maximum as 4.5, allowing intermediate values of 1.5 and 3.0,
which correspond to the scale divisions, so that the Y axis will be
labelled:
Qe oop
C1 € Cn
This gives the maximum vertical spread of plot points.
Having made this decision, the user can input the maximum and
minimum Y axis values. The decision can also be made to return to the
start of the first module and re-define the values of X, choosing a
different range (choosing to calculate for X = 1.5 to 7.5, for example,
rather than the original choice of 0 to 6 for the range). This re-
calculation can be done repeatedly until the best possible Y values for
placing on the graph have been found, within the constraints of the
ranges of X that are acceptable.
Derive scale factor for Y axis.
5
5.1 Input minimum Y for scale (Y1).
5.2 Input maximum Y for scale (Y2).
393
Note: These values are the same as will be inserted as scale values in
string form for printing on the display.
5.3 Scale value for Y plot is number of plot points on Y axis
divided by maximum Y minus minimum Y. This is
(DY = 30/(Y2 — Y1) for ZX81, 120/(Y2 — Y1) for Spectrum.)
Note: Next module of program inputs scale values as strings and the
strings for titles to be printed to the screen.
6 Input scale values and titles.
6.1 Input Minimum Y.
6.2 FOR each remaining Y axis scale division (2 to 4).
6.3 Input scale value to be printed.
6.4 NEXT Y axis scale division.
6.5 Print maximum and minimum X value (MINX and MX)
as reminder of X axis values.
6.6 FOR each X axis scale division (1 to 6).
6.7 Input scale value to be printed.
6.8 NEXT X axis division.
6.9 Input Graph title, Function or subtitle, X axis and Y axis
titles.
This algorithm is coded in the program as the subroutine (lines 1000 to
1680), called after initialisation of the arrays (lines 50 — 80). On return,
all necessary data has been input or calculated. The main program
prints the scale divisions on the ‘graph paper’ area of the screen, using
two sets of nested loops (lines 130 — 230). Note the bypass condition in
line 200 to prevent unwanted horizontal lines being printed.
Scales and titles are then printed to the appropriate screen locations
(lines 250 — 340).
The plotting routine (lines 350 to 380) takes each value from the
array N, finds the difference between this value and the defined
minimum Y value (Y 1), and multiplies by the scale factor to get the Y
axis plot position. Plot position is adjusted by the addition of constants
to the X,Y values to be plotted, to place plot points within the graph
paper area. These are:
X axis: 10 on ZX81, 40 on Spectrum
Y axis: 13 on ZX81, 52 on Spectrum
The printout is obtained using COPY.
Variables Table
X$(6,4) Array to store X axis scale values (Input)
Y$(4,5) Array to store Y axis scale values (Input)
T$(4,25) Array for X, Y axis titles, graph titles (Input)
N(50) Array to store calculated Y values
E Loop variable
394
L Loop variable
F$ Function input as string
x Value of X
MINX Minimum value of X (Input)
MX Maximum value of X (Input)
DX Step value for X value in calculation
= Value of Y calculated. Each value stored in Array N(50)
MAXY Maximum value of Y
MINY Minimum value of Y
M$ Menu choice (Input)
Y1 Minimum value of Y axis scale (Input)
Y? Maximum value of Y axis scale (Input)
DY Scale factor for plot of Y values
Flowchart ‘‘“GRAPH’’
Initialise
col Calculate
Scale
factor for
X
Calculate
Y values,
Store in
ағға
Print
Titles,
Scales
395
396
Restate Yes
X value
No
Input Y
Sco le
Values
Calculate
scale
factor for
Y
Return
Spectrum modifications:
The different plot screen of the Spectrum must be taken into account.
This affects scale factors and the actual plot routine, and requires a
larger array for the data (values of Y for the function of X).
In the same area of the screen, where the ZX81 has 50 X axis plot
points, the Spectrum has (4 x 50), 200. The array N must thus be
initialised as N(200). The scale factors for Y and X also need to be
calculated according to this changed plot resolution. Line changes
needed are as follows:
80 DIM N(200)
360 FOR F=1 ТО 200
370 РГОТЕ-40, (N(F) - Y1)*DY + 52
1120 LET DX = 200/(MX - MINX)
Delete lines 1135 and 1265
1156 FOR F=1 TO 200
1236 FOR F=2 TO 200
1380 LET DY = 120/(Y2 - Y1)
1390 Delete 30, Insert 120
1520 Delete 30, Insert 200
Spectrum users can also use the DEF FN and FN instructions to define
the function to be plotted (in line 1050) and to evaluate the function
within the calculation loop (line 1160). Revise the program to utilise
these functions when they have been dealt with in Section W.
Sample printout
aS шаш ЖОЛ Ode c AUT ee `
+ + + + +
+ + + & + +
FUNEM * + + +
3-0 +----+--- -—+——-- +
+ + = + Ф e
+ + + + + €
RX IS + +u + + + e
= = += E
1:5 t---w4y"t----t----t----t----t
+ F + + + + i
+ ж + + + + <
+ а” + + + £ £
тя + + + + ғ
e meee pee KK tem KH tor Ф
e 1.80 2.8 3.8 4.0 5.5
GRAPH PLOT OF ESUaT Zor
SIN x+x
Program listing
10 REM "GRAPH"
20 REM *PRODUCES GRAPH OF
30 REM *FUNCTION WITH TITLES
40 REM жАМП SCALES FOR +VE
*GUADRANT
397
330
DIM Х%(6,4)
DIM Y$(4,5)
DIM T$(4,29)
DIM N(S0)
REM s*GOSUB INPUTS##
GOSUB 1000
CLS
REM **PRINT PAPER ++
2 FOR Е=5 TO 30 STEP 5
FOR L=0 TO 15
PRINT АТ LiF} "+"
NEXT L
NEXT F
FOR L=0 TO 15 STEP 5
FOR F=6 TO 29
IF Ғ/5- INT (Ғ/5) THEN NEXT
J PRINT АТ L»F;"-"
МЕХТ Ғ
МЕХТ 1
REM Ж%%ТІТІ ЕС жж
FOR F=1 TO 6
FRINT АТ 16s(F*5-1); X$ (F)
NEXT F
FOR F=1 TO 4
PRINT АТ 20-F#3107Y$(F)
NEXT F
PRINT AT 1735: T$ (2)
PRINT AT 1890] Реан
PRINT АТ 19sS3TSC137 АТ 215
8#T$(2)(1 TO 20)
340
TAE
250
260
270
250
290
1000
1010
Е"
1020
PRINT АТ 8»0:7%(42(1 TO 5);
0:7%(42 (6 TO 10)
REM **PLOT FROM ARRAY жж
FOR Р=1 TO 50
PLOT F*105s(NCFE2-Y10*DY413
NEXT F
GOTO 9999
PRINT "GRAPH QF FUNCTION"
PRINT »» “CALCULATION ROUTIN
PRINT “INPUT FUNCTION TO BE
. GRAPHED: IN": "FORM Y=FUNCTION X.
1030
PRINT “FUNCTION IS INPUT AS
STRING. "s "ERROR MAY RESULT IN E
*VALUATION",."OF SOME FUNCTIONS, І
F THIS": “HAPPENS: REPLACE STRING
INPUT","AND EVALUATION WITH INSE
КТЕП", "PROGRAM LINES"
1050
1060
1070
1080
1090
1100
1110
1120
1130
1155
1140
INPUT F$
CLS
РКІМТ ss "LOW VALUE OF X7"
INPUT MINX
PRINT з» "HIGH VALUE OF X?"
INPLIT MX
REM 3x*SCALE FACTOR X**
LET DX=50/ (MX-MINX)
REM **CALCULATE жж
FAST
LET X=MINX
398
1150 FOR F=1 TO 50
1160 LET Y= VAL F$
1170 LET N(F2zY
1180 LET X=X+¢1/DX)
1190 NEXT F
1200 REM **GET МАХЭМІМ Үжж
1210 LET MAXY=N(1)
1220 LET MINY=N(1)
1230 FOR Ғ-2 TO 50
1240 IF МСЕ) <МІМҮ THEN LET MINY=
NCF?
1250 IF MAXY<N(F) THEN LET MAXY=
NCF)
1260 NEXT F
1265 SLOW
1270 PRINT "MINIMUM VALUE FOR Y
IS:" MINY
1280 PRINT “MAXIMUM VALUE FOR Y
IS:", MA XY
1290 PRINT »» "CHOOSE SUITABLE VA
LUES FOR Y “;"AXIS (Y) OR RESTAT
E RANGE OF X ","(X)? INPUT X OR
ү. "
1300 INFUT M$
1310 CLS
1320 IF МФ-"Х" THEN GOTO 1070
1330 REM **SCALE FACTOR Ys*
1340 PRINT “INPUT NUMERIC VALUE
OF MIN. Y" | "( <= ":MINY: 'OFOR SCA
1350 INFUT Yi
1360 PRINT “INPUT NUMERIC VALUE
OF MAX. Y".,"C >= ":MAXY: ' 0"
1370 INFUT YZ
1380 LET DY2s30/(Y2-Y1)
1385 REM ** Y AXIS SCALES жж
1390 PRINT "Y AXIS HAS 3 SCALE D
IVISIONS, " “AND ЗО FLOT FOINTS."
1400 PRINT “INPUT THE 4 SCALE VA
LUES FOR Үн» "АХІ5. МАХ 5 CHF:S, "
1410 PRINT “NEWLINE FOR BLANK. "
1420 PRINT "MINIMUMC12»57?"
1430 INPUT Y$(1)
1440 FOR F=Z TO 4
1450 PRINT "VALUE ";F;"?"
1860 INFUT ҮФСЕ)
1470 NEXT F
1480 CLS
1485 REM **X AXIS SCALES**
1490 PRINT “INPUT X AXIS SCALES"
1500 PRINT "LOW X IS " MINX
1510 PRINT "HIGH X IS ":MX
1520 FRINT з» "6 SCALE DIVISIONS:
50 FLOT FOINTSON X AXIS."
1530 PRINT "SCALE VALUES MAX.4 C
HRS, "s "FIRST INPUT IS LOW VALUE.
1540 FOR F=1 TO é
1550 PRINT "SCALE VALUE ";F;"?"
1560 INPUT X$(F)
1570 NEXT F
1580 REM **TITLES#*
1590 CLS
399
1600 PRINT "INPUT GRAPH TITLE (М
АХ 25 CHR)"
1610 INPUT T$(1)
1620 PRINT “INPUT FUNCTION OR SU
ETITLEC2O","CHRS MAX)"
1630 INPUT T$¢2)
1640 PRINT “INPUT X AXIS TITLE ¢
20 CHRS MAX)"
1650 INPUT T$(3)
1660 PRINT “INPUT Y AXIS TITLE¢2
ж5 CHRS) "
1670 INPUT T$(4)
1680 RETURN
9990 REM 3*ENLD*
9999 STOP
6. “ELEMENT”
Problem: To calculate for a chemical compound: (i) Percentage
elemental composition and molecular weight or (1) molecular formula
from inputs of, for (i), Number of atoms each element and for (ii)
Percentages of each element. These are complementary calculations.
Research Problem: We require a program that performs two separate
operations. The common requirements will be the Element names,
symbols and molecular weights. We choose to input and store these as
data in arrays on the computer. This will require an input routine that
is not used every time the program is run, and could be edited out. The
elements involved should be capable of being changed to facilitate
different analyses, and this must be allowed for in our program. This is
an advantage over the alternatives of either defining all data with LET
statements or the use of DATA and READ (which are only available
on the Spectrum).
The program must be split into two processing sections. The first of
these (percentage elemental composition and molecular weight)
requires an input for the number of atoms of each element. We can use
a loop for this, using the loop variable to access the stored element
names. Molecular weight equals the number of atoms of each
compound multiplied by the atomic weight. This can be calculated
within the input loop. Molecular formulae are then derived from the
atomic symbol, plus the number of atoms, for each of the elements
concerned.
Percentage composition for each element is the number of atoms of
the element, times the atomic weight of the element, divided by the
molecular weight.
The second section of the program requires an input loop for the
percentage of each element. The proportion of atoms of each element
will then be the percentage divided by atomic weight. This can be
calculated within the input loop. To calculate the molecular formula,
we require to know the minimum (to give us the smallest number of
400
atoms of any of the elements) elemental proportion. We can check this
through another loop. The number of atoms of each element is then the
proportion of each element divided by the smallest proportion. We
could round this to integers, but will do so to two decimal places
because the actual molecular formula may be a multiple of the derived
formula. We should also indicate this possibility to the user.
Zero inputs will be required when elements do not occur in the
compound concerned.
For a common organic analysis the following data will be stored via
the input routine:
HYDROGEN H 1.008
CARBON C 12.01
NITROGEN N 14.008
OXYGEN O 16.00
PHOSPHOROUS p 30.98
SULPHUR 5 32.06
CHLORINE CL 22,427
BROMINE BR 79.916
The data entry module is keyed in and the data input as above. The
lines 15 to 160 could then be deleted if required, leaving the data stored
in the arrays and available for access, as long as RUN is not used (or
CLEAR). Spectrum users should replace line 3000 with: 3000 SAVE
“ELEMENT” LINE 3010. The program is then SAVEd to tape by
using GOTO 3000, when it stops at line 1990, or run again by keying
in GOTO 200 as a command.
You may like to derive an additional user dialogue to ask if the user
wishes to SAVE or re-run the program, and according to the response,
send control to the relevant line number. The procedure for the
program is given below.
Detailed Procedure:
1 Data Entry Module
1.1 Dimension arrays for data: Element Names, Element
Symbols, Atomic Weights
FOR each input (1 to 8)
Input Name, Symbol, Atomic Weight
GOTO subroutine to justify atomic weight (5 below)
NEXT input
Print user warning about the use of RUN
ка кА ы ы қа
O олњ OG N
2 Menu
2.1 Print Instructions and Menu
2.2 If second calculation required, GOTO 4
2.3 If first calculation required, proceed to 3
401
3 Percentage Element Calculation
252
3.2
4.4
Input:
3.1.1 Reference for compound
3.1.2 Initialise arrays, molecular weight variable
3.1.3 ^ FOR each Element (1 to 8)
3.1.4 Input number of atoms present
3.1.5 Calculate total molecular weight (Molecular weight
plus (number of atoms * atomic weight))
3.1.6 NEXT Element
Processing/Output:
3.2.1 Print Reference, Molecular Weight
3.2.2 КОК each Element (1 to 8)
3.2.3 Print Symbol, number of atoms
3.2.4 NEXT Element
3.2.5 КОК each Element (1 to 8)
3.2.6 If no atoms present, GOTO 3.2.10
3.2.7 | Calculate percentage as (Number of atoms times
atomic weight) divided by molecular weight of
compound, times 100
3.2.8 | GOSUPB (5) for rounding and justification of results
3.2.9 | Print Element symbol, percentage
3.2.10 NEXT Element
4 Molecular Formula Calculation
Input
4.1.1 Reference for compound
4.2
Initialise Arrays
FOR each Element (1 to 8)
Input percentage present
Calculate proportion of Element as percentage
present divided by atomic weight
4.1.6 NEXT Element
Processing/Output:
4.2.1 Print reference
4.2.2 Set C = 100 for percentage calculation
4.2.3 FOR each Element (1 to 8)
4.2.4 TH proportion is zero, GOTO 4.2.6
4.2.5 If proportion less than current value of C, then let C
equal proportion of element
4.2.6 NEXT Element
4.2.7 | FOR each Element (1 to 8)
4.2.8 If proportion is zero, GOTO 4.2.12
4.2.9 Number of atoms equals proportion divided by
smallest proportion present, C
4.2.10 | GOSUB (5) for rounding and justification to 2 d.p.
4.2.11 Print Symbol, number of atoms
6.2.12 NEAT Element
4.2.13 Print user warning that multiples of this calculated
formula may be the actual formula
402
5 Subroutine to Round and Justify
(Input of number of decimal places (P) and number to be
Justified (N) from data defined in main program modules)
6
1)
2)
1 X$ set to contain P zeros
2 Integer value set as XN
3 Decimal value set as XD
4 Define X$ as rounded number string
5.5 X$ returned to main modules for printing
Auto-run. An automatic RUN routine using GOTO 200 is used to
prevent the user entering RUN accidentally after LOADing
Variables Table
Input and main program sections:
Holds element names
Holds element symbol
Holds atomic weight
Loop variable in main program
Loop variable in input routine
Menu choice
Reference for compound
Molecular weight
Holds input of number of atoms of element
Holds input or calculated percentage of element
Holds calculated number of atoms of element
Constant for calculating percentages
Round and justify subroutine:
N
X$
XN
XD
F
Holds number for operation of subroutine
Holds string form of number returned by subroutine
Holds integer value of N
Holds decimal value of N
Loop variable in subroutine
403
Flowchart “ELEMENT”
START
DIMENSION
DATA ARRAYS
INPUT
DATA
INPUT
CHOICE
<> YES
NO
INPUT
INPUT
PERCENTAGE
FIND
LOWEST
PERCENTAGE
CALCULATE
FOR EACH
ELEMENT
NUMBER
NUMBER OF
OF ATOMS
ATOMS
PRINT
PRINT REF,
SYMBOL, NO
MOL.WT,
OF ATOMS
FORMULA
CALCULATE
PERCENTAGE
PRINT
INSTRUCTIONS
STOP
FOR EACH
ELEMENT
PRINT
PERCENTAGE
404
FOR EACH
ELEMENT
FOR EACH
ELEMENT
Program Listing
10 REM "ELEMENT"
15 REM 33499) )9 3 9 9 9 9 9 3) (99€
1. DATA ENTRY. ROUTINE
CAN BE DELETED WHEN
ENTRY COMPLETE.
325553555554
20 DIM Е%с(8:310)
30 DIM 5%(8»20
40 DIM МСЕ)
50 PRINT ~ ELEMENT SYMBOL
MOL. WT. "
55 PRINT
60 FOR X=1 TO &
ез REM ** ELEMENT МАМЕ жж
70 INFUT Е%(Х)
75 REM ** ELEMENT SYMBOL жж
20 INFUT S$*$(X)
85 REM ** ATOMIC WEIGHT жж
90 INPUT MCX)
75 REM *INITIALISE FOR GOSUBs*
100 LET Рс
110 LET N=M(X)
120 GOSUB 2000
130 PRINT X: TAB S;E$(X); TAB 1
4;S$€$(X); TAB (27- LEN X$); ХФ
140 PRINT
150 NEXT X
160 REM
жн INES 15 TO 160 CAN BE
DELETED AFTER DATA ENTRY
AND REST OF FROGRAM ENTERED
MUST USE #60TO 200% TO USE
PROGRAM: NOT RUN: TO PRESERVE
DATA.
170 REM **END 1. жж
ЭН
180 REM
200 REM 33933399 3 99 00€ EHH (90
2, FROGRAM MENU ТП
CHOOSE CALCULATION
CEEE ETETE EEEE EEEE EEEE EE
210 PRINT "CHOOSE CALCULATION Е
EQUIRED: - "
220 FRINT
230 PRINT "TO INFUT NUMBER OF A
TOMS AND GETPERCENTAGE ELEMENT С
OMPOSITION AND MOLECULAR WEIGHT
INPUT E"
240 PRINT
250 PRINT “TO INPUT PERCENTAGE
ELEMENT ANA-LYSIS AND GET MOLECU
LAR FORMULA INPUT M"
260 INFUT A$
270 IF AS <> "E" AND AS <> "M"
THEN GOTO 260
280 CLS
290 IF A$-"M" THEN GOTO 1000
405
295 КЕМ жж END 2, жж
+++ Ж JE ЗЕ JOE 555552555555
хх 3€ 3€ € 3€ 3€ 9€ 3€ 9€ € € 9E € EE CE
З. PERCENT ELEMENT
ЗЕ ЭЕ ЗЕ ЗЕ ЗЕ ЭЕ ЗЕ AE FE ЭЕ ЭЕ ЗЕ ЭЕ ЭЕ ЗЕ ЗЕ ЗЕ ЭЕ ЭЕ ЭЕ ЭЕ 55)
300 PRINT "ENTER REFERENCE FOR
THE COMPOUND"
310 INFUT F$
320 REM жж INITIALISE жж
230 DIM A(S)
240 LET MOLWT=0
200 DIM PCS)
360 FOR Е=1 TO 3
270 FRINT "NUMBER OF ATOMS OF "
TESE) 7 "2"
380 INPUT ACE)
390 LET MOLWT=MOLWT+ CACE) *MCE2)
400 NEXT E
410 CLS
420 REM **CALCULATE AND PRINT#*
X*RESULTS жж
430 PRINT "MOLECULAR WEIGHT AND
COMF' QS IT LON ХА 9€ 9€ 3€ 3€ 3€ 96 9€
хын
440 FRINT
450 PRINT "ЕЕЕ: "ЕФ
460 PRINT
470 FEINT “MOL. WEIGHT= "s: MOLWT
480 PRINT
490 PRINT "MOL. FORMULA: ";
S00 FOR E=1 TO 8
510 IF А(Е221 THEN PRINT S$(E);
ACE»;
520 IF AtE?)z1 THEN РЕІМТ Z$(E»;
wow NEXT Е
240 PRINT “a "os
220 FOR Есі TO
260 IF АСЕ) =0 THEN GOTO 620
565. REM *xCALCULATE FERCENTAGESZ*
370 LET РХ(Ео-А(ЕзожМСЕО /MOLWT*
100
575 REM *INITIALISE FOR FOLIND2
x3xSLEROLUTINE EE
380 LET МЕСЕ)
990 LET Pe2
£00 GOSE 2000
610 PRINT "FERCENT ";5%(Е); TAB
(198- LEN ХФ) 7 X$
620 NEXT E
&22 REM **xCOPFY HERE FOR FEINTED
*hFEZULTZ xk
230 GOTO 12500
406
640 REM жж END 3. жж
355555555524 55553554
é50 REM
290 REM 3JX9 393339 Ж 33 3333333333
4, MOLECULAR FORMULA
HHH HAH HH HHH HHH HHH HEHE
1000 PRINT “ENTER REFERENCE FOR
COMPOUND"
1010 INFUT F$
1020 REM **IIM ARRAYS+*+*
1030 DIM ЕСЕ)
1040 DIM NCE)
1050 РЕІМТ
1060 REM жжІМРІТ FERCENTAGES**
1070 FOR E=1 ТО 8
1080 PRINT "РЕРСЕМТ OF ";E$¿(E);"
1090 INPLT PCE)
1095 REM **CALCULATE FROPORTION®
1100 LET N(E)=P(E)/M(E)
1110 NEXT Е
1120 CLS
1120 REM **#CALCULATE AND PRINT**
RESULTS жж
1140 FEINT “*MOLECULAR FORMULA*"
: ТАР OF "ххх € 39€ 3€ 9€ 3€ 9€ HE"
1150 FRINT
1160 PRINT "REF:";:R$
1170 PRINT
1175 REM **CALCULATE MINIMUM 3s
XxPROPORTION ELEMENT жж
1180 LET C-100
1190 FOR E-1 TO 8
1200 IF МСЕ) =0 THEN GOTO 1220
1210 IF N(E)<C THEN LET C=N(E)
1220 NEXT E
1222 REM **DERIVE FORMULA **
1230 FOR E=1 TO $Š
1240 IF NCE)=0 THEN GOTO 1290
1250 LET Р=2
1260 LET NzN(ED/C
1270 GOSUB 2000
1280 PRINT S$(E); TAB 5- LEN X$;
X$
1290 NEXT Е
1295 REM жжЖСПРҮ HERE FOR PRINTED
X*RESULTS жж
1300 PRINT »s"MULTIPLES OF THIS
FORMULA MAY", "BE THE ACTUAL FORM
ША IF AT “s"“LEAST 2 ATOMS OF EA
CH ELEMENT": "PRESENT"
407
"CASSFILE''
1320 REM
** END 4. жж
3C JC 3C HHH HHH 3E EXE ETE IEE HE
1780 КЕМ
1790 КЕМ
X*ENDREUN INSTFELICTIGONZ33*
1800 PRINT AT 20:07 "USE GOTO 200
TO RUN AGAIN. "» "USE GOTO 2000 T
О SAVE"
15910 STOP
1220 REM
жжжж END PROGRAM *33*
1530 КЕМ
7000 FEM хх ххх А *
5. SUBROUTINE TO ROUND
AND JUSTIFY
EMR 3C 26 Ae ut 3C HEH ЕЕ Жы
2010 LET X$z""
2020 FOR Ғсі TO P
2030 LET X$=X$+"0"
2040 NEXT F
2050 LET XN= INT М
2060 LET XD= INT (10 ж F*(N-XN)
+0, 5)
2070 LET Х%- STR$ XN+". "+(X$(1 T
Q P- LEN STE$ XD)+ 5ТЕ% XD+X%$)(1
TO P3
2080 RETURN
2070 КЕМ ** END SLE **
+ + ЖЕ ЗЕ AE FEFE FE 3E ЗЕ ЗЕ ЭЕ PE ЭЕ FE ЭЕ ЭЕ ЭЕ ЭЕ ЗЕ ЭЕ
О REM
) REM 3999 3 9) 0 3 ж ЭЕ 3 3€ A Зє
AUTO-RUN ROUTINE
HHH HEHEHE 355555555555
3000 SAVE "ELEMENT"
3010 GOTO 200
3020 REM #* END FROGRAM LIST жж
Problem: То write a program which will store and manipulate the data
concerned with cassette program listings and print out lists of these
files. The data must be able to be updated. Cassette labels should be
printed out, taking advantage of the fact that the Sinclair printer paper
is the correct width for this.
Research the problem: The program must have data entry and
and storage for relevant data. This data must be displayed on screen
and printed out if required. There must be a facility to add, delete and
revise each portion of data separately. Data must be stored in string
and numeric arrays, and there should be protection from accidental
408
clearing of the stored data by the use of RUN. However, since more
data may be required to be stored than will fit in one set of arrays, there
should be also a facility to clear the file data arrays deliberately, to
allow a new file system to be set up. Any other variables must be
defined by LET statements, and all variables re-initialised after
CLEAR has been used.
The best method of setting up a structure for this type of program is
to have a menu presented to the user. From the menu, control can be
passed to a separate module of the program which will perform the
appropriate manipulations. After each set of operations have been
performed, control will pass back to the menu module, which is the
main program, looping back after each call (via а GOSUB or GOTO
instruction) of the other program modules.
Outline Procedure:
Initialise storage arrays, variables, strings.
Present menu options.
Pass control to selected area of program.
Required are program modules to:
Input data (create a file)
Print a file (screen and printer)
Revise a file
Delete a file
Print cassette label
Erase all files
Control returns to (2) on completion of each operation.
5 Adding a Save files procedure will enable an auto-run system to
avoid the risk of using RUN, and wiping out data.
H OF N н
Detailed Procedure:
1 Define the data to be held, its form, variables needed in the
program, and strings to be used by one or more program sections
to print titles for data. Initialise arrays, variables, strings. (See
data table below.) This module is processed only once for each
file system.
2.1 Present Menu: 1 Create File
2 View/Print File
3 Revise File
4 Delete File
5 Print Cassette Label
6 Save Files
7 Erase all Files
2.2 Loop back to start of Menu. If CLEAR has been used in 4.7,
loop to (1).
409
4.1
4.2
4.3
4.4
4.5
4.6
Go to chosen program section. Use subroutines unless this causes
problems.
Create File.
4.1.1 Define file number (existing files + 1)
4.1.2 Input data
4.1.3 Increment file count
4.1.4 Sub-menu: View created file (GOSUB 4.2)
Create another file (GOSUB 4.1)
Menu (RETURN)
4.1.5 Return to Menu
View/Print File
4.2.1 Get file number to view
4.2.2 Print file contents on screen
4.2.3 Sub-menu: Print file to printer (COPY)
View next file (GOSUB 4.2)
Menu (RETURN)
4.2.4 Return to Menu
Revise File
4.3.1 Get file number to revise
4.3.2 Print each item on screen
4.3.3 Input new data if required, leave if correct
4.3.4 Print new data if input
4.3.5 Return to Menu
Delete File
4.4.1 Get file number to delete
4.4.2 Print basic file data (name, reference)
4.4.3 Confirm deletion
4.4.4 Delete file contents
4.4.5 Swap data from files of higher number to maintain file
numbering as sequence
4.4.6 Print new file numbers and basic data (reference and
name)
4.4.7 Sub-menu: Copy new file listing (COPY)
Menu (RETURN)
4.4.8 Return to Menu
Print Cassette Label
4.5.1 Get file number
4.5.2 Print file contents on printer in suitable form
4.5.3 Return to Menu
Save Files
4.6.1 Allow revision of program name (string)
4.6.2 Allow return to menu if error
4.6.3 Stop program until cassette ready
4.6.4 Save ‘program name string’
4.6.5 GOTO Menu (prevent use of RUN)
Note that this module cannot be a subroutine. Auto-run routines on
410
the ZX81 do not operate from within subroutines properly, so control
must be passed with GOTO instructions. This procedure is modified
for the Spectrum (see notes below).
4.7 Delete all files
4.7.1 Confirm deletion
4.7.2 Use CLEAR to delete data
4.7.3 Set marker for re-initialisation of variables on Return to
Menu
4.7.4 Return
This cannot be a subroutine on the Spectrum (see notes below).
The marker informs the main program loop that control must be
passed to module (1) for re-initialisation.
Each section of the program must then have the detailed procedures,
including input checks, defined. Each area of the program can be
treated as a program module for coding purposes. The sections must
operate on the same data structures, so the first task is to define the
arrays for the data, variables required, and strings for printing, so that
a table of these may be used in developing each section of program.
Data Table
C$(10,4) Holds cassette reference (any four characters)
N$(10,15) Holds cassette name (15 characters)
P$(10,10,15) Holds for each cassette file 10 program names (15
characters)
T(10, 10,2) Holds for each program on each cassette tape
counter readings (Start and Finish, numbers
assumed to be in range 0- 999)
F File number of Ше being manipulated іп
processing
IF Total number of files (up to 10)
M$ String input from menus
M Numeric input from menus
S$ Current file program name
N,L Used as loop control variables
E$ Set as empty string for overprinting
A$,B$,F$,G$
H$,1$,X$,Y$,Z$ Used as string literals for printing
x Marker to show CLEAR has been used and hence
that re-initialisation of variables and arrays is
required.
Another consideration is whether recursive or nested subroutines
should be used. Care must be taken in the use of these facilities, and
unnecessary complication should be avoided, since all control is passed
back to the Menu, from which all modules can be accessed. However,
411
in the program recursion is used in the Create File routine to allow a
sequence of data entries to be made (Line 1280), and (Line 2300) in the
View File routine to allow stepping through the files.
The View File routine is also available as a nested subroutine from
the Create File routine to allow a newly created file to be viewed (Line
2020). Apart from these instances a simple GOSUB - RETURN
pattern of control has been followed, and the control flow in the Save
Files routine has the same structure, but using GOTO instructions for
the reason stated above. The different action of the CLEAR instruction
on the Spectrum requires a GOTO instruction for the Erase All Files
module (see below).
Ten files are set up and manipulated in this program. Reference to
the way variables are stored (Section T) will enable you to discover the
memory required for this. The same section has the PEEK routine to
discover program size. Work these out. You will find that the program
could in fact store and manipulate up to 30 such files on the ZX81.
Display file size will restrict the 16k Spectrum user to ten files, as in the
program.
The main program flow is illustrated in the first flowchart. The
nested and recursive structures in the program are illustrated in the
second, with the sub-menu control structures also shown. Sub-menus
include a “Return to Main Menu” option.
412
Flowchart ‘‘CASSFILE’’
1. Main Program Flowchart
START
DIMENSION
ARRAYS,
INITIALISE
6899
SAVE FILES
MODULE
1909
CREATE
GOSUB FILES
(M*1000)
20909
% VIEW/
PRINT FILES
413
CONTINUES SAVED
PROGRAM ON
LOADING
REVISE
GOTO MODULE
ON SPECTRUM
2. Recursion and Nesting the Create File and View File Subroutine
MENU
ENTER CREATE
FILE NUMBER FILE SUB-
=FILES+1 ROUTINE
(LINE 1000)
INPUT
NEW FILE
DATA
INCREMENT
NO. OF
LINE 1230
No RESPONSE “Ғ”
= CREATE
ANOTHER FILE
INCREMENT
FILE
NUMBER
GOSUB RECURSIVE
1020 GOSUB
114
RESPONSE
"V" = VIEW
CREATED FILE
GOSUB (A) FILE MODULE
AS NESTED
SUBROUTINE
Yes
z ү
415
INPUT
START OF VIEW
FILE FILE SUBROUTINE
NUMBER (LINE 2000)
ENTRY FROM
CREATE FILE
MODULE
FILE Y
EXISTS -
2
енуге -- VIEW
ANOTHER FILE
“M” = RETURN
TO MENU
LINES 2120 TO
2185
RETURN
(TO LAST
GOSUB CALL)
YES
COPY
416
“F” = VIEW NEXT
FILE
FILES =
FILES + 1
CHECKS IF FILE
EXISTS
RECURSIVE
GOSUB
Spectrum Modifications:
1 Тһе Spectrum has a simplified auto-run procedure and printing
the prompts is done automatically. Make the following line
changes:
9950 PRINT “PRESS A KEY FOR SAVE ROUTINE”
9960 PAUSE 0
9970 SAVE S$ LINE 9980
This whole module (lines 6000 onwards) could be a subroutine on
the Spectrum (unlike the ZX81, it will SAVE from a
subroutine), but it should then be a self-contained subroutine,
417
without the jump at line 6100. The placing of the auto-run
routine at the end of the program is done so that it is more visible
to the user, since there is not a STOP or Program End.
Replace SCROLL in lines 3090, 3150, 3170, 3230, 3250, 3265,
3420 and 3495 by POKE 23692, - 1.
The Spectrum wipes the GOSUB stack when CLEAR is used.
This means it will not have a location stored to RETURN to.
The Erase All Files module must therefore use GOTO
statements:
325 ЕМ =6 OR M =7 THEN GOTO M* 1000
7090 GOTO 350
Program Listing
5 LET S="CASSFILE#1"
10 REM "CASSFILE"
20 DIM С%(1034)
30 DIM М%(10:15)
40 DIM Р%(10%10315)
50 DIM ТС1і0» 10,2)
60 LET X=0
70 LET F=0
80 LET E$z"
YO LET A$z"CASSETTE FEF: '
100 LET B$-"CAZSETTE NAME"
110 LET F$z"FILE NO, "
120 LET G$="PROGRAM NAME"
130 LET НФ-"ТАРЕ COUNT"
140 LET I$="FROM ТО"
150 LET TF=0
140 LET X$= SS eee
—— |
170 LET ҮФ- U ea CFP
120 LET 7%- "4
I"
190 REM Js 909
171 REM **MENLI**
192 РЕМ 33333
200 PRINT 5%
210 PRINT ТАЕ 103 "MENLI"
220 PRINT
220 FRINT "1. CREATE FILE"
„240 PRINT »» “2. VIEW/FRINT FILE
250 PRINT »»"3. REVISE FILE"
260 PRINT з» "4. DELETE FILE"
270 PRINT »» "5, PRINT CASSETTE
LABEL"
250 PRINT з» "4. SAVE FILES"
290 PRINT з» "7. ERASE ALL FILES
300 PRINT s> “INFUT YOUR CHOICE"
310 INFUT M
320 IF М<1 ОЕ М>7 THEN GOTO 300
325 IF Mzé THEN GOTO 6000
330 CLS
340 GOSUB M*1000
418
350 CLS
355 IF X=1 THEN GOTO 20
360 GOTO 210
290 REM KEKE t9 € € 9€ 9€ € € 9E 9€ € EE
жж CREATE FILE SUE жж
+++ 3C + 3E 9E 3E 3€ EXEC EE EXE E XE JE EXE XE
1000 LET F=TF+1
1010 IF F <= 10 THEN GOTO 1020
1015 PRINT "««NO SPACE FOR АМОТН
ER ҒЕПЕжж"») "ОМ RETURN TO MENU
CHOOSE SAVE", "OPTION TO KEEF CUR
RENT FILES"."THEN ERASE FILES AN
D START NEW": "FILE ARRAY. "
1016 FAUSE 300
1017 RETURN
1020 PRINT "READY TO CREATE FILE
NO. "FF
1030 PRINT АТ 2:0;7"INFUT CASSETT
E REF. (4 CHRS MAX)"
1040 INFUT СФСР)
1050 PRINT АТ 2:0;E$; АТ 230: B$:
"?(15 CHRS MAX)"
1060 INPUT МФ СР)
1070 PRINT АТ 230:Е%: АТ Z230:"IN
PUT FROG. NAMES AND TAPE COUNTS"
1080 PAUSE 300
1090 FOR М=1 TO 10
1100 PRINT АТ 4:0; "PROGRAM "FN
1110 PRINT 6$;" ? (15 CHRS MAX)"
1120 INPUT РФС(Ғ»МО
1130 PRINT АТ 5з0:Е%; АТ 5% О0:Н%;
" FROM ?"
1140 INFUT TCFsNs1)
1150 PRINT АТ 5,11;"ТО ? ы
1160 INFUT TCF »Ns2)
1170 PRINT АТ 530:Е%: AT 5» 0; "АМ
OTHER FROGRAM ?(Ү/М2"
1180 INFUT M$
1190 IF M$="N" THEN GOTO 1220
1200 IF M$ <> "М" AND M$ <> "Y"
THEN GOTO 1170
1210 NEXT N
1220 CLS
1225 LET TF=TF+1
1230 PRINT "CREATE ANOTHER FILE
(F) VIEW" s “CREATED FILE (V) OR M
ЕМ) (M)?" |+" INPUT F»V OR W "
1240 INPUT M$
1250 IF M$ <> "F" THEN GOTO 1290
1260 LET F=F+i
1270 CLS
1280 GOSUB 1020
1290 CLS
1225 IF M$-"V" THEN GOSUB 2020
1300 RETURN
1980 REM «эке кен
1990 КЕМ жж VIEW FILE SUB ** +
1991 REM HHH 0909090 (3 9 9 EERE
2000 PRINT "WHICH FILE NUMBER?"
2010 INPUT F
419
2015 REM **ENTRY FROM OTHER SUBS
2020 CLS
2030 IF TF <> 0 AND F <= TF AND
F >= 1 THEN GOTO 2110
2040 PRINT "NO FILE WITH THAT NL!
2050 PRINT "MENU (M) ОЕ VIEW OTH
ЕК FILE 7"
2060 INFUT M$
2070 IF M$="V" THEN GOTO 2000
2080 IF M$-"M" THEN RETURN
2090 PRINT "FOLLOW INSTRUCTIONS
PLEASE. "
2100 GOTO 2050
2110 CLS
2120 PRINT FSF
2130 PRINT A$ CSIF?
2140 PRINT "Жж 3€ 3€ 3€ 9€ 9€ 9€ E 9€ 3€ 9€
JC 3C3€ 3€ 3€ 3€ 3€ 3E 9€ 9E 3E '"
2150 FRINT G$; ТАЕ 20;H$? TAB 20
; 1%
2160 PRINT "--------------------
2170 ҒОЕ N=1 TÜ 10
2180 PRINT Nr", "ЭРФС(ҒЭ М9? TAB 20
ТЕМ 12; TAB 26: TCF» NS Z2
2185 NEXT М
2190 PRINT АТ 21:0: "ҒЕІМТСР 2» МЕХ
T ЕПЕСҒ; OR MENLICM) "
2200 INFUT M$
2210 PRINT AT Z1:0;E$
2220 IF M$z"P" THEN COPY
2230 IF MS «> "Е" THEN GOTO 2510
2240 LET Е=Е+1
2250 IF F <= TF THEN GOTO 2200
2290 DLS
2260 PRINT "**NO FILE OF HIGHER
NUMEEF3 * "
2270 FALSE 150
2280 CLS
2290 GOTO 2210
2200 GOSUE zozo
2310 RETURN
КЕМ 9333 33t3(t3€ 9€ 3€ EHH
REM **xREVISE FILE SUB**
795) REM ххх HHH HHH 3
OO PRINT "WHICH FILE TQ REVISE
1 Tu АҒ
3010 INFLIT F
2020 IF F <= TF THEN GOTO 3060
3050 PRINT “NO SUCH FILE"
3040 FALZE 120
3080 RETURN
fat А к F3
3060 CLS
3070 PRINT "FILE "Рӯ" DETAILS W
ILL BE PRINTED. "ss" PRESS NEWLIN
E IF CORRECT" » “INPUT NEW DETAILS
IF REQUIRED. "
420
3080 PAUSE 150
3090 SCROLL
3100 PRINT AS; СФСР)
3110 INPUT M$
3120 IF МФ-"" THEN GOTO 3170
3130 LET C$CF)-zM$
3140 CLS
3150 SCROLL
3160 PRINT "NEM ":a$:C$(F?)
3170 SCROLL
3180 FRINT BS;" "МСР
3190 INFUT M$
3200 IF M$-"" THEN GOTO 3265
3210 LET N$(F)=M$
3220 CLS
3230 SCROLL
3240 PRINT A$ CCF?
3250 SCROLL
3260 FRINT "NEW CASS. NAME "МСЕ
)
3265 SCROLL
3270 FOR N=1 TO 10
3350 FRINT "FROG. "FN?" NAME ":P$
(Fs ND
3370 INPUT M$
3400 IF M$ <> "" THEN LET ҒФСЕ» М
)zM$
3410 PRINT AT 21:0; "PROG. "№" N
AME ";PSCFsN)
3420 SCROLL
3430 PRINT AT 21,0; "ТАРЕ FROM: ";
Т(Ғ» М» 12
3440 INFLIT M$
3450 IF M$ <> "" THEN LET ТСР» №
1)= VAL M$
3460 PRINT АТ 21%0: "ТАРЕ FROM: ";
TCFsNo i337" TO: "ТЕУ N6 22
3470 INFLIT M$
3480 IF M$ <> "" THEN LET ТСЕ» М,
2)= VAL M$
3490 PRINT АТ 21,0; "TAFE FROM: ";
T(FsN3512;" TO: "ТСЕ М2)
3495 SCROLL
3500 NEXT N
3510 RETURN
2990 REM 3J333 93333) 9 X 3X ы €
4000 REM x*xxDELETE FILE SUB**
4001 REM «ххх Хы CE
4010 PRINT “WHICH FILE DO You WI
SH TO".,."DELETE ? (1 TO 10)"
4020 INPUT F
4030 IF F <= TF AND F >= 1 THEN
GOTO 4070
4040 PRINT "x«NO FILE OF THAT NL!
MBER»* "
4050 FAUSE 150
4060 GOTO 4430
4070 FRINT F$;Fs АФ: C$ CF)
4080 PRINT B$:" ":N$(F)
4090 FRINT АТ 10:0;"INPFUT D TQ C
ONFIRM DELETION"::3»"OR M FOR MEN
LI, и
421
4100 INPUT M$
4110 IF M$ <> "D" THEN GOTO 4430
4120 PRINT АТ 1430;"ALL FILES WI
TH NUMBERS >"3Fs"WILL HAVE THEIR
FILE NUMBERS", "REDUCED BY ONE, "
4125 IF F=TF THEN GOTO 4220
4130 FOR N-F TO TF-1
4140 LET N$(N)=N$(N+1)
4150 LET ССМ) C$ (N12
4160 FOR L-1 TO 10
4170 LET PS(NsLI=P$(N+15L)
4180 LET T(NsL+1)=T(N+1s+sL+1)
4190 LET T(NsL+2)=T(N+1+L $22
4200 NEXT L
4210 NEXT N
4220 LET C$(CTFO-E$
4230 LET N$(TFO-E$
4240 FOR N=1 TO 10
4250 LET P$¿(TF+N)=E$
4260 LET T(TF+N+1)=0O
4270 LET ТТР» №2) =0
4280 NEXT N
4290 LET TF=TF-1
4300 CLS
4310 PRINT "FILE DELETED"
4320 PRINT »% "МЕМ FILE LISTING: "
4330 PRINT
4340 FOR N=1 TO TF
390 PRINT РФ №" “FASS ССМ)
4360 NEXT N
4370 FRINT AT 21:0; "COPY NEW LIS
T (G), OR MENU СМ)"
4380 INPUT M$
4390 IF M$ <> "C" THEN GOTO 4430
4400 PRINT AT 2130;:E$
4410 COPY
4420 CLS
4430 RETURN
4990 REM 333999 9 9 0 9 9 309€ 9€ ыы
2000 REM 3x* PRINT LABEL SUEs3«*
5010 REM 93sÓ3dmdUK3t3(93€((€ Y HEHE
5020 PRINT "WHICH FILE DO YOU WA
NT ТО РКІМТ"»% "А5 А CASSETTE LA
BEL? 1 TU 19 3”
5030 INF'LIT F
5040 IF F >= 1 AND F <= TF THEN
GOTO 5090
5050 PRINT "#*NO FILE OF THAT МІ)
MBER жж"
5060 PAUSE 150
5070 CLS
5080 GOTO 5220
5090 PRINT ›› "ЕЦЕ "ФЕ" WILL NO
W BE PRINTED. “%%% "СНЕСЕ PRINTER:
HIT А KEY TQ START"
5100 IF INKEY$ ="" THEN GOTO 510
©
2120 LFRINT X$; "i"; A$:C$(F); TAB
20rF$r:F; TAB Sir" F
5130 LPRINT 2%: "| “2 БФ)! "3 МСР);
TAE 212
422
5140 LPRINT 2%:Х%: "8 "0%; TAE ZO
2% "УНФ: ТАЕ зір
5150 LFRINT "I": TAB 20941") I$;
TAB 31" B"
5160 LPFINT X$
170 FOR М-1 TÜ é
2180 LFRINT "Ё": №" ЗРФХРЭМО T
AB 21:Т(ҒэМ1»: TAE ZS58:TCF»N$Z27
TAB 31: "8"; Z$
510 NEXT N
a400 LFRINT Y$; ХФ
5210 LPRINT wee ТАЕ 20
;F$:F; ТАЕ 31;"I"
5220 LPRINT ҮЗІГІ "*5N$CF2;
TAE 1? " ["
3230 ІРЕІМТ Y$; X$
740 FOR N=7 TO 10
5250 ІРЕІМТ "[";N:" "PCF No? Т
АЕ 21: ТСҒ»Мз1»)) TAB 25% TCFs М2);
_ AE 313" I":Z
5260 NEXT N
3270 LFRINT Y$
52280 RETURN
5990 REM 33339 )9 99 9 9 4! 9 9 3 3 HEHEHE
6000 REM ** SAVE FILES PROC жж
6001 REM 3333 9999) HEHEHE ене
6005 CLS
6010 PRINT "SAVE FILES ON ТАРЕ Е
OUTINE"
Т PRINT ss "CURRENT PROGRAM МА
ME Is"
6030 FRI NT , 5 и пи и , 2$; "Ç "un "“
6040 PRINT эз"ІМРІТ А NEW NAME F
OR THIS “s"“FROGRAM FILE OR PRESS
NEWLINE":"ONLY TO SAVE WITH CUR
RENT NAME. "
6050 PRINT ss "INPUT M FOR MENU"
6060 INFUT M$
6070 IF M$="M" THEN RETURN
6080 IF M$=""" THEN GOTO 9900
6090 LET 5%-М%
6100 GOTO 9900
6990 REM J3JQdUqcd(eogdndde 9) 99 9 9)
7000 REM **DELETE ALL FILES SUE
LE EEEE EEEE EEEE EEEE EEE EE]
7010 PRINT "INPUT D TO CONFIRM A
LL FILES" ARE TO BE. DELETED. ^
7020 PRINT ss “INPUT M TO RETURN
ТО MENU. "
7030 INPUT M$
7040 IF M$ <> "D" THEN GOTO 7080
7050 CLEAR
7060 PRINT ss “INPUT NEW NAME FOR
THIS. FILE"
7070 INFUT 5%
7080 LET X=1
7090 RETURN
2890 REM 3 39 * X X X34 Ж Ж
9900 REM жж AUTO-RLIN ROUTINE +
2901 REM 3J3sd3J33393 33 ЭЕ ЭРЭР 9€ ЗРЗЕ ыж
423
Sample Printout:
9910 CLS
9920 PRINT “PROGRAM NAME IS "
29°30 РЕ T NT и ии и - = $ 5 и ии "<
9940 PRINT "#*NOTE IT DOWN3*"
9950 PRINT :»"SET CASSETTE TO FE
CORD АМО THEN" "PRESS A KEY TO
SAVE. "
9960 IF ІМКЕҮФ ="" THEN GOTO 9926
9970 SAVE 5%
9280 CLS
9990 GOTO 200
FILE NO.1
CASSETTE REF: ЯРР1
£ £ £ X x % X % X X X X £ £ X X £ X S 33 S a $ $ $ +
PROGRAM NAME TAPE СОЫМТ
FROM то
1.GRAPHPLOT s 29
2.RESIST з= exu
3.STRINGSORT ес аза
4. e a
S. а ж
б. & г.
Ta ғ Pu
в. e гы
ә. e гы
29. e e
CASSETTE REF:RHPP1 FILE NO.i
t CASSETTE NAME BRPPLICRHTIUONSÓ1
PROGRAM NAME TREE COUMT
FROM то
GRAPHPLOT
RESIST
STRINGSORT
CASSETTE REF:APP1 FILE MO. |
CASSETTE NAME RPPLICRHTIGOPFSsi
424
Comments:
This is a fairly long program. Work through the listing, checking you
understand the operation of the algorithm within each program
module. The individual manipulations of arrays and lists have all been
encountered before, and each program module performs a different
operation on the arrays and lists holding the data. The program is not
by any means ‘idiot-proof’, although it is reasonably ‘user-friendly’
and you should note the various input checks used. The program can
be crashed by inputs of bad (non-numeric) data into the numeric array
holding the tape counter listings, and the main menu. Any file number
request is checked.
The input (string or numeric) from menus is checked, in different
ways. Either another input is requested, or a default return to the main
menu operates. Data correction is dealt with by the View File and
Revise File modules.
The program could be improved in two obvious ways. The first
improvement would be a search routine to find and display the cassette
file containing a desired program. A new module, 8 in the main menu
and line 8000 onwards in the program listing, could be added to
perform this operation.
The second is that you cannot both print a file (in the View/Print
File module) and then step through for the next file, since after printing
the program automatically returns to the menu. Consider how you
would modify the flow of control in lines 2190 to 2310 to allow this.
Notice as a final point that data manipulation programs are long, not
necessarily because of the processing manipulations themselves, but
due to necessary input checks and user dialogue.
The program can be easily revised for use with your audio cassette
library, or other filing purposes.
The program examples included in this Unit have been selected to
illuminate the various structured programming techniques discussed in
the rest of the book. In order to demonstrate the maximum number of
these techniques being used in practice, it proved necessary to give the
programs a strong scientific applications bias. Home users will
doubtlessly be dismayed to discover that there is little in this part of the
book which will be of practical use to them. However, it is important
that they understand the principles behind the programs in this Unit,
even if they do not actually key them in.
As far as games and home applications programs are concerned, the
Program Library at the end of the book (Appendix VI) should provide
readers with enough examples to enable them to write their own
programs tailor-made to their particular interests.
V4: Games Programming
Games are applications programs which are not of a type which fulfils a
425
specific purpose in a functional context; that is to say they are not
written to do a specific scientific, educational or data-manipulation
task. This does not mean that, as programming tasks, they are
frivolous. The enjoyment of playing the game on or with the computer
is the application for which the program is written, but the task of
programming a game is often difficult. Games programming is good
practice for finding, deriving and coding algorithms and producing
efficient and user-friendly programs. Graphics manipulation plays a
larger part in games programming than in most applications programs,
and such programs are also more interactive, requiring repeated inputs
and outputs.
BASIC, an interpreted language, is often slow for games purposes.
Fast action graphics games (SPACE INVADERS and their spawn),
are written in machine code for speed of operation, as are tactical
games where exhaustive exploration of possible moves is required (such
as chess). Effective games can be programmed in BASIC, however, if
the amount of calculation is not too great.
An area of interaction between Games and Application
programming is the question of simulation. A program, given data and
rules for manipulating the data, simulates a situation. In a serious
application, this would be a real situation, with the manipulations
performed as known or hypothesised relations from scientific
knowledge. A game simulation would use invented relationships, or
perhaps simplified formulae, if it dealt with a ‘real’ situation. The
techniques would be essentially the same, and are used in a program in
the same fashion. From the point of view of this book, games may be
considered as programming exercises. All the techniques you have
learnt can be put to use in writing games programs.
V5: Example Programs
The first program we will examine 15 a classic computer simulation, or
rather implementation, of Life. This is not really a game, but a process
that the user sets into operation, and observes. Invented by John
Conway, the game simulates a colony of cells, which grows from the
initial colony according to three simple rules. Cells are placed on a
grid, and in each generation the succeeding generation is determined
by the number of neighbouring grid squares which contain a cell. The
rules are these:
1 Ifa cell possesses, іп the 8 adjacent grid squares, either two or
three neighbour cells, it survives into the next generation.
2 А сей dies (is removed from the grid for the next generation) if it
has (1) 4 or more neighbouring cells (overpopulation) or (11) 0 or
1 neighbours (isolation).
3 Each grid square which is empty, but has exactly three
neighbours is a birth cell, and a cell will appear in this position in
the next generation.
426
To implement this on the computer,
manipulation will be involved since a grid is a 2-D array. It is also
necessary to have more than one such array, since the grid of
Generation (n + 1) is defined from the grid of Generation (n), and none
of the cells of Generation (n) can be altered until the checking process is
complete.
The array of Generation (n) must have each grid position checked,
and the number of neighbours counted. In accordance with the rules,
the future of the cell at that position is determined and, if empty,
whether a cell will be born. This data is stored in one array, and then
the other array is updated to take account of the changes. Spectrum
users should delete lines 220 and 390.
Program Listing
S REM "LIFE"
10 PRINT TAB i1z:"*LIFE«"
20 FRINT
20 DIM 85(16%162
40 DIM Bcté.1ié)
50 DIM Ас, 2)
80 LET GEN=0
70 REM #ENTES START COLONY+*
SO PRINT "ENTER START COLONY";
"ON A Xé GRID"ssse"INFUT 6 STRI
NGS OF SPACES AND "."AZTERISKZ ¢
жу"
70 PRINT
100 FOR F=1 TO ё
110 PRINT "STRING ";F;
120 INFUT A$CF)
130 PRINT " “SASCF)
140 NEXT F
145 REM xFLACE COLONY IN ARRAY*
150 FOR F=1 TO é
140 FOR Z=1 TO ë
170 IF A$(FyZ)="*" THEN LET ЕСЕ
+9, 1+5) =1
120 МЕХТ 2
170 NEXT F
200 GOSUB 1000
205 REM *INCREMENT GENERATIONS
210 LET GEN=GEN+1
220 FAST
230 FOR Х=2 TÜ 15
240 FOR Үс2 TO 15
250 REM *SET COUNTER*
260 LET C=0
265 REM *CHECK NEIGHBOUR CELLS
270 IF А(Х-1:Ү) =1 THEN LET C=C+
1
280 IF ACX-isY-1)=1 THEN LET C=
С+1
290 IF АсХ-15Ү+1)=1 THEN LET C=
C+1
300 IF A(X:Y+1)=1 THEN LET C=C+
1
310 IF ACXsY-13=1 THEN LET C=C+
1
427
it is obvious that array
320 IF ACX4+1;Y-1)=1 THEN LET C=
+1
330 IF ACcX41»Y2021 THEN LET C=C+
1
340 IF ñ(X+1yY+1)=1 THEN LET C=
[^41
34& REM xDECIDE IF BIRTHx
350 IF ACX:Y220 AND Cz3 THEN LE
T BCX*Y2z1
255 REM *#DECIDE IF DEATH*
360 IF А(553Ү9гті AND (Crt OR С<2
) THEN LET ECX:Y)=0
370 NEXT Y
3S0 NEXT X
390 SLOW
400 GOTO 200
1000 CLS
1002 PRINT АТ 931: "GENERATION ";
GEN
1010 FOR X=1 TO 16
1020 FOR Y=1 TO 16
1025 REM ЖИРПАТЕ ARRAY Аж
1030 LET ACX» YOzBCX YO
1035 REM *PFINT ARRAY*
1040 IF ACX:Y)=1 THEN PRINT AT X
+Z 153 OH”
1050 IF А(ХзҮз-0 THEN FRINT AT X
T2iY46:" "
1060 NEXT Y
1070 NEXT X
1080 COPY
1090 RETIREN
428
Flowchart of “LIFE?
START
INITIALISE
ARRAYS,
GENERATION
PRINT
INSTRUCTIONS
PRINT
STRING
NUMBER
PLACE IN
ARRAY B
429
INCREMENT
GENERATION
COUNTER C
= No. of
NEIGHBOURS
FOR A(X,Y)
A(X,Y)
(OCCUPIED
NO
=1
B(X,Y) =1
(BIRTH)
430
Flowchart of ‘ІЕЕ’ - Subroutine 1000
ENTRY
PRINT
GENERATION
COPY
SCREEN
RETURN
431
PROGRAM STRUCTURE
The program breaks down into the following sections.
(1) Initialisation (lines 30 — 60). Two 2-D arrays, 16 x 16 are set up,
with a 6 string array to hold the start colony. The generation
counter is set as 0.
(üu) Input of start colony (lines 70 — 140). 6 strings of 6 characters are
entered and printed out.
(iui) Start colony is placed in array. The lines 150 — 190 place 1
(representing a cell) in array B when an asterisk is present in the
string array entered in (11), in the central 6 x 6 block.
(iv) Print Subroutine. Line 200 sends control to the subroutine. This
uses a double loop to set array A as array B, then prints asterisks
on the grid for each 1 found in array A. Note that at the end of
this subroutine arrays À and B hold the same data. The screen is
copied, and control returned to line 210.
(v) Checking of population to determine next generation. The
generation is incremented and the computer put into FAST
mode. The double loop is set up, and each cell in array A is
checked in turn for the number of neighbours it possesses. The
counter C is incremented by 1 for each neighbour. Line 350
places a ‘born’ cell into array B if the cell in array A is blank,
and the number of neighbours is three. Line 360 kills any cell
with more than 3 or less than two neighbours. The
corresponding array B element is set to 0. At this point array B
holds the revised population for the next generation. Array À
must be left alone during the check procedure. This is the reason
why the two arrays are made equivalent in (iv) above.
(vi) Control is returned to line 200, and steps (iv) and (v) repeated.
The pattern of asterisks input initially determines how the population
develops. Some patterns die out, after a number of generations, some
enter a stable sequence that repeats, and there is a general tendency
towards symmetry if a population survives long enough.
The next game is also an implementation of a favourite game for
computers, which has existed since the days of printout-only terminals
(which is where the instruction PRINT in BASIC comes from, as a
hangover from hard-copy terminals transferred to implementation on a
screen). The basic idea, upon which many variations have been
created, is that a landing must be made on the lunar surface at a speed
low enough to prevent a crash. Rockets can be fired to slow the craft,
but the fuel supply is finite. If the fuel supply is exhausted, a crash is
inevitable. The game was originally played with a printout of the data
432
only. This version uses one side of the screen for a graphic display, and
prints the data on the other. Spectrum users must replace line 40 with
40 PAUSE 0.
2 REM "LANDER"
10 PRINT TAE 10; *LANDER*";: AT
4,0; "LUNAR LANDING GAME. YOU ARE
"S"INITIALLY 500 METRES ABOVE T
HE", "SURFACE OF THE MOON. YOLI НАМ
E “5 "100 "FUEL UNTTS "
ZO PRINT "FRESS Е TO FIRE ROCK
ETS TO SLOW DESCENT. EVERY FIRING
USES 5 FUEL UNITS. YOU MUST LAND
SLOWER THAN z TO SURVIVE. GOOD L.
ШЕ, "
30 РЕІМТ з» "FRESS A KEY TO STA
КІ”
40 FALSE 40000
45 REM ** I NITIALISEx*
SO CLS
&O PRINT АТ 20315) "deka
ulis "
70 LET Fz100
mO LET Н==00
90 LET 5-15
72 REM **xzTAOàRT OF ІППРжж
100 LET V=0
110 IF Hz&OO THEN РЕІМТ АТ 20-Н
/30320;" "
120 PRINT AT 105 “FUEL: “РЕТ "а"
: TAB O:"HEIGHT:":H;" "? TAB O;"
SPEED; "3355" "
135 REM *#*#CHECK ROCKETS жж
140 IF INKEY$ ="F" AND F >= 5 T
HEN LET V=Š
150 IF V THEN PRINT AT Zi-H/30:
203" Vy"
160 IF F<5 THEN PRINT АТ 1з7: "%
EMPTY +"
170 LET FeF=y
180 LET S=S+2-V
190 PRINT АТ 20-H/30; 20; " ii
TAB 20; " 4
192 КЕМ жж СНЕСЕ IF LANDED жж
200 IF H<30 THEN SOTO 230
210 LET HzH-Z
220 GOTO 100
225 REM ** LANDING RESULT жж
230 IF 5<4 THEN PRINT АТ 21,10;
"PERFECT LANDING"
240 IF 545 AND 524 THEN PRINT А
Т 21310: "BUMPY BUT SAFE"
220 IF © >- & THEN PRINT АТ 21,
10: "CRASHED AND SMASHED"
260 PRINT АТ 1230: "ANOTHER GAME
?СІМРИТ Y OR ND"
270 INFUT AS
433
ЕО IF A$z"Y" THEN GOTO 20
то REM *END*
2
2
4--
в.
Lines 10 to 30 print instructions, and line 40 stops the program until а
key is pressed. Lines 50 to 90 clear the screen, print the “lunar surface'
and set the variables: F is fuel units, H is height above surface, S is
speed of descent.
The main program is in the loop between lines 100 and 220. V is set
to zero as a flag, and the craft is printed by line 110 if the scale set
allows it to be on screen. The craft disappears off the top of the screen if
the height is greater than 600 since the PRINT AT instruction scales so
that 1 print line = 30 metres of height. Line 120 prints the current data.
Note the spaces after the variables to overprint if the values decrease,
or in the case of the speed becoming positive after being negative.
(Negative descent speed means ascent.)
Line 140 checks if the R (for rockets) key is being pressed. If it is, V
Is set to 5. Line 150 prints rocket exhausts below the craft if the R key
was pressed (evaluated by V = 0 = False if not pressed, V = 5 = True if
pressed). The fuel is checked (line 160) and reduced by the value of V if
not empty. The speed is adjusted by increasing it, then reducing it by
the value of V if the rockets have been fired. Line 190 overprints the
craft and rockets, and 200 checks if the surface is near enough for
landing to be assumed. If it is, control is transferred to the landing
message section. If not, the height is adjusted and the program loops
back to repeat the process.
Notice that the variable V is used in three ways within the loop, and
that the loop structure, using INKEYS to see if the player has input
instructions, is common in interactive games. It provides a simulation
of a real-time process. In this game, the speed is assumed to be metres
per second (hence the simple LET H = H - S of line 210). It is actually
nominal ‘metres’ per program loop! Other games can wait for inputs,
but the use of a loop allows the inexorable attraction of gravity to go on
its way unless the player does something. Spectrum users, with their
faster computing, may wish to insert a PAUSE instruction in the loop.
Programming for this type of game can show the programmer that
certain structures of programs are inefficient in program execution,
since conditional branches to routines requiring calculation will
noticeably slow the loop. In the interests of a good game, structured
programming practice may be set aside and speed of execution can
become a goal in itself. However, remember not to transfer these
techniques to serious programs!
Games programming can become extremely complex when we
consider the strategy and tactics which must be built into the response
from the computer. We have dealt with only the simplest form of game,
and have not included any of this type of game. We suggest that you
434
put to work the techniques we have shown you in this text to analyse
some of the tactical games in the popular computing magazines, if this
area Interests you. In order to start learning to appreciate the problems
involved, you could start by writing a program to play Noughts and
Crosses. You may think this is a very simple game, but it is a
surprisingly difficult one to program!
435
E
o
f
СОЖ быш
—
2
s
PART FIVE
COVERING THE WHOLE
SPECTRUM
чон YET wig)
4° SYM
SECTION W: THE SPECTRUM
W1: The Spectrum System and Keyboard
This Unit introduces the Spectrum microcomputer system. As a
Spectrum user you have been referred to this Unit because, whilst the
BASIC language that both the Spectrum and ZX81 use (Sinclair single
keystroke BASIC) has only minor differences between the two
machines (although the Spectrum has additional features that the
ZX81 does not possess, such as colour, high-resolution graphics and
sound), there are greater differences in the arrangements of the
keyboard. The Spectrum system is also simpler to set up and connect.
After reading this Unit, you should return to the start of Section C
(page 19) to start using the BASIC language, once the keyboard and
the way to access all the confusing array of characters grouped on and
around each key have been explained. Sections A and B are for the
ZX81 only, but you will find in this Unit the same information as it
applies to the Spectrum. The main text takes you through the Sinclair
BASIC language, using the same instructions for the ZX81 and
Spectrum, any minor differences being noted. This involves the
introduction of a few of the Spectrum’s enhanced BASIC instructions,
but most of the additional facilities of the Spectrum are covered in the
next Units, to be read after you have worked through the main text and
have learnt the BASIC programming techniques.
SPECTRUM SYSTEM DESCRIPTION
We assume that you have in front of you the components of your
Spectrum system.
This consists of:
1 The ZX Spectrum microcomputer.
2 Either 16k of internal RAM or 48k (although nothing in this
book demands more memory than 16k).
3 The ZX power supply, with the correct plug attached for the a.c.
power sockets you have.
4 The ZX printer and its socket.
5 A domestic TV to act as a display monitor.
6 A mono cassette recorder, with an a.c. supply lead (if not battery
powered).
7 The aerial/antenna cable which connects the Spectrum to your
TV set. (In the U.S. this is via a switch box.)
8 A pair of cassette recorder leads, fitted with 3.5mm jack-plugs at
either end.
These components make up a complete system, the least crucial part of
which is the ZX printer. If you do not have a printer then you can
ignore the printer-related sections of this book and learn BASIC
439
programming techniques just as well. It is extremely useful, however,
to have a printer both for hard-copy printouts of results and, more
importantly, for program listings for documentation purposes.
The cassette recorder should preferably be mono, since stereo tape
deck recording heads can cause problems, even used on only one
channel. The cheaper recorders work somewhat better (due to the less
sophisticated audio circuits being better for handling the crude form of
the computer’s signals) than more expensive ones, but get one with a
tape counter, as finding programs without one can be an irritatingly
time-consuming process.
FIGURE 3
SPECTRUM SYSTEM DIAGRAM
a.c. household power supply
TV AERIAL
CONNECTION
POWER
SUPPLY
TELEVISION
9V d.c.
кезі
PRINTER
CASSETTE //
RECORDER Ж
U.S. Users тау have antennae on/off switch
fitted in aerial lead, shown as dotted box in diagram.
440
FUNCTION OF COMPONENTS
Here is a brief rundown of the function of each of the components of
the Spectrum microcomputer system.
Device
Spectrum computer board
Keyboard
TV Set
Cassette recorder
Printer
Power Supply
Cables
Function
Data processing and control of inform-
ation handling.
Input from keyboard or cassette. Output
to ТУ screen and printer. Also holds the
16k or 48k of RAM memory. K stands
for kilobyte. One byte is eight bits, which
are the binary digits (0 and 1, represented
by on-off switches in the computer)
computers work with. A kilobyte is
roughly 1000 bytes, hence the name. (It
is actually 2^, 1024).
Input of information. Programs, data
and commands are keyed in.
On-line control.
Used as V.D.U. (visual display unit)
monitor. Provides on-line output of
information - visual display of programs,
results (data, graphs, pictures) and
control commands.
Off-line storage of information Program
data are stored (written) as coded
electromagnetic impulses on cassette
tapes. They can be played back (loaded)
at any time for use again. The computer
reads the data from the tape. The
Spectrum will also be able to use the
microdrive, storing the coded impulses
on a magnetic-coated disc, when it
becomes available.
Output device, to provide a permanent
printed record of the screen display,
program listings or information in the
computer memory. Prints on electro-
sensitive paper.
Supplies the d.c. current (9 volts at 1.2
amps) to run the computer, RAM pack
and printer, from the household power
supply.
To interconnect the devices which make
up the system.
The printed circuit board inside the Spectrum holds and connects the
441
IC (integrated circuit) microchips which provide the computing
facilities. These are:
1
4
Z80A CPU (Central Processing Unit) microprocessor chip
which is the heart of the system. It is used in many other
microcomputers, and performs the arithmetic manipulations.
ROM (Read Only Memory) chip holds the 16k BASIC
interpreter which translates BASIC instructions into the
machine-code instructions that the 780А operates with. The
data in this chip is fixed, hence the name, and also stable - it
remains when the power is switched off.
RAM (Random Access Memory) chips provide the memory
store. This is either 16k or 48k, depending on which version of
the Spectrum is owned. This memory is volatile — the data is
stored as electrical impulses and is lost when the power is
switched off. This memory stores the BASIC program, the
values of variables (including some system variables that the
computer uses for to organise its own affairs), a memory picture
of the ТУ screen display, and the stacks which hold the numbers
whilst they are being manipulated. The memory organisation is
described in Section U.
The Logic Chip co-ordinates the operation of the other chips.
Also mounted on the board are the stabiliser for the 5 volt supply the
computer takes from the power-supply socket, the colour TV signal
encoder and modulator circuits and the sockets for the connecting
cables to the ТУ and cassette recorder. There is also a small speaker for
the sound output.
CONNECTING UP
1
2
Set aside an area to work in and set up your television,
Spectrum, cassette recorder, printer (if you have one) and the
Spectrum’s power supply, as shown in the diagram of the system
(Fig. 3).
Always remember to connect the printer to the back of the
Spectrum before you switch the power on for the ZX power
supply. With the printer connected, the TV aerial lead
connected to the ТУ socket on the Spectrum, and the ‘EAR’
and ‘MIC’ leads correctly set up as below, you can then plug into
and switch on the a.c. power (household) supply.
Connect the printer into the socket at the rear of the
Spectrum. Make sure the gap in the board at the rear of the
Spectrum connects with the plastic piece in the printer socket,
then push firmly home.
Connect one end of the twin cassette leads into the EAR and
MIC sockets of the cassette recorder. Push firmly home and
twist slightly to get good connections. Take the same colour plug
442
as is in the EAR socket of the cassette recorder and place it in the
Spectrum EAR socket. Place the other in the MIC socket.
Inset the Jack-plug leading from the power supply into the
socket marked 9 V d.c. on the back of the Spectrum. Connect
the TV aerial/antenna lead to the aerial socket of the TV.
Your system is now set up. Check the ТУ is turned off, and no
cassette keys are depressed. Plug the ZX power supply and
cassette leads into the a.c. (household) power supply sockets,
and switch them on if they have switches.
3 Switch on the TV. Choose a channel with the push button or
other channel select control, and tune the TV until the display:
(O 1982 Sinclair Research Ltd
appears on the screen. Adjust the tuning until the display is
clear, and the brightness, contrast and colour (if you're using a
colour TV!) controls to get a good picture without it being too
bright (since you are going to spend some time looking at it from
close up).
Note for U.S. users: In the U.S., the antenna lead connects
with standard terminals to the TV. An antenna on/off switch is
provided between the computer and the TV. The computer has
a channel select switch to select channel 2 or 3. Whichever
channel is not transmitting should be selected, and the TV
tuned until the computer display is obtained.
4 Press a few keys to get some characters printed on the
screen — these should appear at the bottom of the screen. Then
press the CAPS SHIFT and 1 (EDIT) keys together, to clear the
screen.
5 Press the Z key. The screen will print COPY at the bottom.
Then press ENTER. The printer will start operating, feeding
paper through. There will be nothing printed on it because there
is nothing printed on the screen. Check that the printer paper
does not rub against the side of the printer as it is fed through. If
it rubs, pull it gently away from the side as the paper is fed
through.
You now have an operating microcomputer system. The system needs
no maintenance other than the occasional cleaning of the printer and
the tape heads on the cassette player. Clean the printer with a small
brush to clear away the black dust that accumulates. Be careful not to
damage the electrode (a small piece of wire running in the slot visible
when the paper carrier is removed). Blow away the dust when you've
brushed it from this slot. Keep your cassette tape heads clean and de-
magnetised.
If the printer doesn't work, first turn off the power. Then remove
and re-insert the printer socket. Switch the power on again and try
once more. The contacts on the printed circuit boards that the printer
443
socket connects with may need cleaning if the printer doesn't work or
prints incorrectly. Clean the contacts with a proprietary contact cleaner
or a pencil eraser. DO NOT use abrasives to clean these contacts.
These are the only problems you should encounter with your system,
as long as all plugs are well seated in their sockets. With the need to
remove and re-insert the EAR socket when saving programs on
cassette tape, you must take care to always re-insert the jack-plug
properly each time.
THE KEYBOARD
The Spectrum keyboard has 40 keys arranged in 4 rows of 10. At first
sight, it might appear similar to a typewriter keyboard, but on closer
inspection you will see that keys have 5 or 6 functions or characters. In
fact:
Eight different characters and functions
can be obtained with some keys!
The keyboard contains:
1 The digits 0 to 9
2 The letters of the alphabet printed in upper and lower case
(capitals)
3 The complete BASIC language:
— instructions
— commands
— arithmetic, conditional and logical operators
— arithmetic functions
4 Grammatical signs and symbols
5 Special control keys
6 Graphics symbols
These are all called characters, and are on, below or above the keys
used to access them.
Notice that words like PRINT, LIST, RUN, etc are all printed on
the keyboard and also appear on the screen with a single key press.
The Spectrum’s ability to print complete words in the BASIC
language at the press of a single key is called:
SINGLE KEYSTROKE BASIC
On most other computers you have to key in each letter of, for
example, the instruction PRINT. This is obviously inefficient. The
Spectrum is very powerful in this respect. The keyboard contains all
the characters in the Spectrum’s character set, together with a few
special keys. Some 200 ог so different characters are available. Some
print to the screen, others are non-printing (e.g. DELETE).
444
CUP
BLUE RED MAGENTA GREEN pn "S LOW m BLACK
EDIT CAPS LOCK TRUE VIDEO INV. VIDEO GRAPHICS DELETE
17 2 9 Rt RUP T ` „Лл в d Her
DEF FN OPEN я CLOSE * MOVE ERASE POINT CAT
г.
ae c LA 0 E о
БАЯ Mus R Á J; ы» IU
VERIFY MERGE
ES DATA
AF i su ы ғ oe
ENTER |
sm oe Ht ЖӘ K
CIRCLE VAL$ SCREEN$ а
|с? UN B N M
E ЕЗ | SPACE
ЕР 2 oe и> C 2 V: Z Bs М os ЕЗ | SPACE
PAPER FLASH BRIGHT OVER
ANVSOVIO a WNYLIAdS
r aunbi4
THE CHARACTER TYPES ON THE SPECTRUM KEYS
The Spectrum keyboard, to handle the enhanced version of Sinclair
BASIC that runs on the Spectrum, has to accommodate more
functions. This has been done by using basically the same layout as the
ZX81 keyboard, but incorporating an additional shift key, which
provides the capacity to access the additional colour, graphics, sound
and microdrive functions which are present on the Spectrum but not on
the ZX81. The Spectrum has an enhanced character set also, with
additional text characters (@, ©, [, ],~, etc.) not in the ZX81
character set.
As this book deals with the ZX81 computer as well as the Spectrum,
the treatment of additional facilities of the Spectrum is kept to this
separate Spectrum Section, although some comments are made in the
general text about these facilities where appropriate. However, you
must learn how to access all the characters on the keyboard as a first
priority.
The keyboard is very complex and it will take some time for you to
find your way around it with ease. It is best described in terms of how
the characters are accessed and the cursors that indicate which mode
the computer is in. The mode determines how the pressing of a key (a
keystroke) is interpreted. Each key has multiple meanings for the
computer, depending on the mode and whether either of the SHIFT
keys (CAPS SHIFT and SYMBOL SHIFT) is being pressed at the
same time as the keystroke occurs.
You will notice that more characters are available from the top row
of keys. These incorporate the colour control and graphics characters.
(The inverse graphics are not shown on the key.) Here are examples of
the two types of key:
E Mode CAPS SHIFT
CAPS SHIFT BLUE %- COLOUR CONTROL CHARACTER
CHARACTER EDIT (in appropriate colour)
(white) G Mode. Unshifted
eh —— Graphics Character
K and MODES G Mode Shift gives
UNSHIFTED DIGIT Inverse Character ( IK in this case)
CHARACTER
K and L Modes SYMBOL
SHIFT CHARACTER (red)
E Mode SYMBOL SHIFT
CHARACTER (Red)
ROW 7 KEYS Example is the 1 key
446
/ E Mode UNSHIFTED CHARACTER (green)
SIN
L Mode UNSHIFTED
жей K апа L Modes SYMBOL
LETTER CHARACTER —> Q (= | - SHIFT CHARACTER
(lower case)
PLOT <.
K Mode UNSHIFTED CHARACTER
CHARACTER
(upper case) ^
E Mode SHIFT CHARACTER (red)
OTHER KEYS Example is Q key
There are also the keys for ENTER, CAPS SHIFT, SYMBOL
SHIFT, and the SPACE key (with BREAK printed above SPACE).
See the keyboard diagram. We must now describe the modes the
computer can be in, and the cursors that indicate the mode. There are
also two other cursors which we will deal with here.
MODES
When inputting (keying in) program lines the position for the next
entry is indicated by a cursor on the screen. The mode is indicated by
the flashing cursors [E] .
The mode (Keywords) and (Letters) may be used unshifted,
with CAPS SHIFT or with SYMBOLS SHIFT. Letters of the
alphabet are lower case unless the CAPS SHIFT key is used or the
mode used. The mode (Capitals) is obtained by pressing CAPS
SHIFT and CAPS LOCK simultaneously and is identical to the L
mode apart from producing capitals (upper case) instead of lower-case
letters. To return to mode press CAPS SHIFT and CAPS LOCK
simultaneously. All letter inputs (REM statements, string inputs and
assignments) in this text are in Capitals. You must use C-mode
exclusively to get listings and printout of letters that correspond to
those in this text.
The mode (Graphics) accesses the graphics characters and may
be obtained using the GRAPHICS key as an on-off switch. Press
CAPS SHIFT and GRAPHICS simultaneously to enter mode.
Repeat to cancel.
447
The mode (Extended) provides the equivalent of the function
mode of the ZX81. It is obtained by pressing CAPS SHIFT and
SYMBOLS SHIFT simultaneously and lasts for one character only.
It may be used unshifted, with CAPS SHIFT or with SYMBOLS
SHIFT.
EFFECTS OF SHIFT KEYS ON MODES
K mode — expecting a command i.e. Keyword mode.
Unshifted - keyword (white word оп 3 bottom rows of
keys)
— digit (white digit on top row of keys)
CAPS SHIFT - keyword (white word on 3 bottom rows of
keys
_ a ЖР (white word above top row of
keys)
SYMBOLS SHIFT - keyword or symbol (red symbol or word
on key)
L, mode — expecting a letter or a number i.e. Letters
mode, giving the lower case letters.
Unshifted — letter (white letter on 3 bottom rows of
keys)
— digit (white digit on top row of keys)
CAPS SHIFT — letter (capitals) (white letter on 3 bottom
rows of keys)
— keyword (white word above top row of
keys)
SYMBOLS SHIFT - keyword or symbol (red symbol or word
on key)
C mode — identical with L mode but Capital letters
are obtained with Unshifted letter keys.
G mode — for accessing Graphics symbols.
Unshifted — graphics character (in grey/white on keys
1 to 8)
— user defined graphic on keys A through
U. (Not shown on keyboard.)
CAPS SHIFT — inverse graphics character (reverse of
symbol on top row of keys)
SYMBOL SHIFT — same as CAPS SHIFT
User defined graphics are dealt with in Unit W2. They are initially
set as the capital letters À to U, which is what appears on the screen.
448
Note that DELETE works in G mode without CAPS SHIFT being
pressed.
E mode - Extended mode, accessing the function
characters in green above the keys in
bottom 3 rows, colour control characters
on the top row,and the function or
symbol characters in red below all keys.
E mode lasts for one character only.
Unshifted — function or symbol (in green above key
for 3 bottom rows)
— colour control (in colour above top row)
CAPS SHIFT — function or symbol (in red below key for 3
bottom rows)
— colour control (in colour above key for top
row)
SYMBOLS SHIFT -function or symbol (in red below key for 3
bottom rows)
— function (in red below key for top row).
The colour control characters print in a program line as the digit of the
key that accesses them, i.e. they are coded 1-7 and 0. If they are
accessed in E mode without INK or PAPER before them, the effect is
to put colour control characters into the display. When unshifted, the
colour control characters change the background (PAPER) colour of
what is placed on the screen thereafter, and when CAPS SHIFT is
pressed, the colour of the character (INK) is changed.
Note: the main body of this text assumes no colours are used, since
the ZX81 cannot produce colour. Colour on the Spectrum 15 dealt with
in Unit W3. Experiment with colour all you want, but this text is
primarily about BASIC programming, and it doesn’t matter what
colour is on the screen for this!
Exercise
Access all the modes, 1.е. get each different cursor on the screen. Key
in all the characters in each mode, first unshifted, then with CAPS
SHIFT, and finally with SYMBOL SHIFT. You will have to enter the
E mode again after each character. Watch what happens with TRUE
VIDEO and INV VIDEO. Notice they reverse each other. Notice you
can’t see a SPACE. Don’t press ENTER, just play around on the
bottom lines of the screen. Notice that the line moves up the screen
when it is filled. Press EDIT with CAPS SHIFT to clear the screen.
You can’t harm the computer whatever you enter. Note that two words
are abbreviated on the keyboard, but print in full- RAND and
CONT.
449
SYNTAX ERROR CURSOR
This cursor appears flashing in a line input at the bottom of the screen
if the computer detects an error in the syntax of the line (i.e. finds an
error in the ‘grammar’ of the BASIC language instruction input). It
appears when ENTER is pressed to enter the line of program or the
command into memory. The cursor appears before the last error in the
line. There may be more than one error, but only one will be indicated
at a time. Editing (making any change in the line) causes the cursor to
disappear. It will reappear if necessary (error not corrected) when
ENTER is pressed once again.
CURRENT LINE CURSOR >
This cursor appears after the line number of the last line entered into a
BASIC program (the current line). If EDIT is pressed (CAPS
SHIFTed 1) this line is brought down to the bottom of the screen. It
can then be edited.
In a program listing of the lines of a program displayed on the
screen, the cursor may be moved to point to different lines by using the
(CAPS SHIF Ted 6) and (CAPS SHIFTed 7) keys to move it down or
up a program line. This is used to select a line for editing.
An important point to note with regard to the keyboard is that the
Spectrum has a repeat key action on all keys. If any key is held down,
after a short time it will automatically repeat.
We now give a table of the characters accessible on the Spectrum
keyboard. Ignore the CODE information for now. This will be dealt
with later. This table is the Spectrum equivalent of Appendix III,
which deals with the ZX81.
CHARACTER SET AND CODES TABLE
This table, which is in alphabetical order, will enable the Spectrum
user to quickly reference any character for:
— its position on the keyboard in terms of a row and column
‘parent key’ address (e.g. A is in the third row and first column
of keys (3,1))
— the mode in which the function may be used (indicated by the
flashing cursor on the screen)
— which keys to press to obtain the function (here SHIFT means
that ether the CAPS SHIFT or the SYMBOL SHIFT key will
give the character)
— the CODE of the character.
450
Character
BEEP
BIN
BORDER
BREAK
BRIGHT
C
C
CAPS LOCK
CAPS SHIFT
CAT
CHR$
CIRCLE
CLEAR
CLS
CODE
CONTinue
COPY
COS
D
d
DEF FN
DELETE
DIM
DRAW
Position
on Keyboard
Row, Column
3,1
` - `
`
~
`
Q3 NO NON h2 h2 CO CO
О S OO — O N Oe
`
Mode(s)
L C
LC
Aidt г сг mmm
t=
—
шлш i p, EA г Gy E":
ОО
LC
о О AR дагог
451
QQ
To Obtain
Press
CAPS SHIFT
SHIFT
SYMBOL SHIFT
SHIFT
SYMBOL SHIFT
SHIFT
SHIFT
SHIFT
SHIFT
SHIFT
SHIFT
CAPS SHIFT
CAPS SHIFT
SYMBOL SHIFT
SHIFT
CAPS SHIFT
SYMBOL SHIFT
CAPS SHIFT
CAPS SHIFT
CAPS SHIFT
ENTER
SYMBOL SHIFT
rh — O < z Q > > >
= = tN 2 % о
CAPS SHIFT SPACE
=
ZU9e-puU жыс-<мшао NOOO
— m tm tz
pa ^!
Code
Character Position Mode(s) To Obtain Code
on Keyboard Press
Row, Column
F 3,4 L CAPS SHIFT F 70
C F
Í 3,4 L F 102
FLASH 4,5 E SHIFT Ұ 72%
ЕМ 1,2 Е SYMBOLSHIFT 2 168
FOR 3,4 K F 235
FORMAT 1,10 E SYMBOL SHIFT 0 268
G 3,9 L CAPS SHIFT G 71
C G
g 3.9 L С 103
GOSUB 3,6 K а ЖИ
GOTO 3,5 K G 236
GRAPHICS 1,10 KLC CAPS SHIFT 0 -
H 3,6 L CAPS SHIFT H т
C H
h 3,6 L H 104
I 2,8 L CAPS SHIFT I 73
C I
i 2,8 L I 105
IF 2,7 K U 250
IN 2,8 E SHIFT I 191
INK 4,3 E SHIFT АЖА 217
INKEY$ 4,7 E N 166
INPUT 2,8 K I 238
INT 2,4 E R 186
INVERSE 4,8 E SHIFT M 221
J 3,7 L CAPS SHIFT J 74
C J
j ы 2 L J 106
K 3,8 L CAPS SHIFT К 75
C K
k 3,8 L K 107
L 3,9 L CAPS SHIFT L 176
C L
1 3,9 L L 108
LEN 3,8 E E іл
LET 3.9 K L 241
LINE 3,9 K L 202
LIST 1,3 K K 240
LLIST 4,5 E V 225
LN 4,2 Е 2 184
LOAD 2,7 K J 239
LPRINT 4,4 E C 224
M 4,8 L CAPS SHIFT M 77
C M
m 4,8 L М 109
452
Character Position Mode(s) To Obtain Code
on Keyboard Press
Row, Column
MERGE 2,9 E SHIFT £ 213
MOVE 1,6 E SYMBOLSHIFT 6 209
N 4,7 L CAPS SHIFT N 78
C N
n 4,7 L, N 110
NEW 3,1 K A 230
NEXT 4,7 K N 243
NOT 5,2 KLC SYMBOLSHIFT S 195
O 2,9 L, CAPS SHIFT O 79
C O
о 2,9 L O 111
OPEN 1,4 E SYMBOLSHIFT 4 211
OR 2-7 KLC SYMBOLSHIFT U 197
OUT 2,9 Е SHIFT O 223
OVER 4,7 E SHIFT N 222
P 2,10 L CAPS SHIFT p 80
C P
2,10 L P 112
PAPER 4,4 E SHIFT C 218
PAUSE 4,8 K M 242
PEEK 2,9 E O 190
PI 4,8 E M 167
PLOT 2,1 K О 246
POINT 1,8 E SYMBOLSHIFT 8 169
POKE 2,9 K О 244
PRINT 2,10 K P 245
о Д.Т L CAPS SHIFT О 81
С Q
q 2,4 L Q 113
R 2,4 L CAPS SHIFT R 82
C R
r 2,4 L R 114
RANDomise 2,9 K % 249
READ 3,1 E ‚А 227
REM 2,2 K E 234
RESTORE 2,4 Е 5 229
RETURN 2,6 K Ү 254
RND 2,0 E Ж 165
RUN 2,4 K R 247
S 2,2 L CAPS SHIFT S 83
C S
S 3,4 L S 115
SAVE 2,2 K S 248
SCREEN$ 3,8 E SHIFT K 170
SGN 3,4 E F 188
SIN 2.1 Е Q 178
SPACE 4,10 SPACE 22
453
Character
SQR
STEP
STOP
STR$
SYMBOLSHIFT
N
N
WOOnNO сл > оо FS Ke ©
Position
on Keyboard
Row, Column
42
- м “ м » EJ `
EI
к. — к л — һа ка ка ка —
о О-О OF ы OO м = =
-
L C
L C
СӘС шшш бу Brot > > D m t Ca Es
С сы DOE
454
To Obtain
Press
SYMBOLSHIFT
SYMBOLSHIFT
SYMBOL SHIFT
CAPS SHIFT
SYMBOL SHIFT
SYMBOL SHIFT
CAPS SHIFT
CAPS SHIFT
SHIFT
SHIFT
CAPS SHIFT
CAPS SHIFT
CAPS SHIFT
CAPS SHIFT
«wie Мих се: AS edie асс "obw < > Ü
NNN
ос со м СУ Q > ON ©
Code
Character Position Mode(s) To Obtain Code
on Keyboard Press
Row, Column
! 1,1 KLE SYMBOL SHIFT 1 33
с 2,10 ELE SYMBOL SHIFT P 34
# 1,3 KLG SYMBOL SHIFT 3 35
$ 1,4 KLE SYMBOL SHIFT 4 36
% 1,5 ELO SYMBOL SHIFT 5 37
& 1,6 KLG SYMBOLSHIFT 6 38
; 1,7 ELE SYMBOL SHIFT 7 39
( 1,8 KL O SYMBOLSHIFT 8 40
) 1,9 K LO SYMBOLSHIFT 9 41
* 4,6 ELO SYMBOLSHIFT B 42
4 3.8 EIL SYMBOLSHIFT K 43
| 3,6 ELO SYMBOLSHIFT H 44
© 4.7 KLC SYMBOLSHIFT J 45
4,8 ELS SYMBOLSHIFT M 46
/ 4,5 KLE SYMBOL SHIFT V 47
4,5 ELO SYMBOLSHIFT Z 58
: 2,9 É L O SYMBOLSHIFT O 59
< 24 ELC SYMBOLSHIFT R 60
» 3.9 KLC SYMBOLSHIFT L 61
» 2.5 KI SYMBOL SHIFT T 62
? 4,4 ELE SYMBOLSHIFT C 63
Q 4,2 ELG SYMBOL SHIFT 2 64
( 26 Е SHIFT Y 91
) > 7 E SHIFT W 93
% 3.3 E SHIFT D 92
^ 3.6 ELO SYMBOLSHIFT H 94
a 1,10 KLC SYMBOLSHIFT Q@ 95
£ 4,3 ЕЗІ SYMBOLSHIFT X 96
i 3.4 E SHIFT F 193
| 3,5 Е SHIFT G 195
| 2,3 E SHIFT S 124
~ 3.1 E SHIFT A 126
© 2,10 E SHIFT P 1⁄2
ы 2,1 KLC SYMBOLSHIFT Q 199
S 2.3 ELG SYMBOL SHIFT E 200
<» 2,2 ELC SYMBOL SHIFT W 201
ate 1,5 EL CAPS SHIFT 5 8
кч 1,8 ELO CAPS SHIFT 8 9
V 1,6 K L G CAPS SHIFT 6 10
À 1:7 K LL G CAPS SHIFT ?. 4d
| |] (space) 1,8 С 8 128
Бы 1,8 G SHIFT 8 143
k 1,1 с 1 129
k= 1,1 G SHIFT 1 142
Е | 12 G 2 136
v 1,2 G SHIFT 9 141
- i G 4, 191
- 1,3 G SHIFT 3 140
[m 1,4 G 4 132
ГЕ 1,4 G SHIFT 4 139
ГЕ 1,5 G 5 133
H 1,5 G SHIFT 5 488
" 1,6 G 6 134
455
Character Position Mode(s) To Obtain Code
on Keyboard Press
Row, Column
m" 1,6 G SHIFT 6 137
" 1,7 G 7 135
B 1,7 G SHIFT 7 136
Colour control characters have no special codes. They have the codes
of, and print as, the digit of the key that accesses them.
They are on keys 1 to 7 and 0.
TRUE VIDEO is on key 1,3. This gives INK on PAPER
colours (black on white on switch-on).
INV. VIDEO is on key 1,4. This gives INVERSE, i.e.
PAPER colour on INK colour
background (white on black if not
coloured).
These use CODE 20 (a control code), and
swap the current INK and PAPER
colours.
Other control codes are as follows:
Control Character Code
Comma for print spacing 6
Number (in memory) 14
Ink control 16
Paper control 17
Flash control 18
Bright control 19
Inverse control 20
Over control 21
Print At control 22
Print Tab control 23
These control characters are used to store required information in the
attribute file (colour commands and characteristics of screen display),
and the display file. They are followed by the values they take.
User-defined graphics have codes 144 to 164 inclusive, and are set,
unless redefined, as the capital letters À to U in sequence. See Unit W3
for more information on this.
W2: Additional Spectrum BASIC Functions
This Unit covers the additional instructions and functions that are
avallable in the Spectrum superset of Sinclair BASIC. First we will
indicate the major differences.
456
SUMMARY OF ADDITIONAL SPECTRUM FACILITIES
The following are the significant differences between the ZX81 and the
Spectrum which have not been dealt with in the main body of the text:
(1)
(ii)
(iii)
(iv)
(v)
(vi)
(vii)
(viii)
(ix)
(x)
(xi)
The Spectrum gives a colour signal to the TV - see COLOUR
in Section W3. Of course, it is still possible to use the machine
on a black and white TV, where different shades of grey will be
obtained when the colour commands are used.
The Spectrum's character set differs from that of the ZX81 and
includes lower case as well as capital letters- see
CHARACTER SET and USER DEFINED GRAPHICS.
The Spectrum's keyboard has additional characters and
functions. You should now be familiar with the functions
treated in the main text. Extended functions are dealt with a
little later in this Unit.
Simple sound production is available using the Spectrum's
BEEP command - see SOUND in Section W3.
The tape storing facilities represent a considerable
improvement on those offered by the ZX81- see TAPE
STORAGE below. The tape LOAD and SAVE speed is
roughly 16k words in 100 seconds, and there is a facility to
merge a program stored on tape with one in memory using
MERGE. The VERIFY facility can be used to check that a
program has saved correctly, as has been noted.
Disc storage and file-handling capability with the microdrive
will eventually be available on the Spectrum, loading 16k
words per second - see OTHER KEYS below.
Additional graphics commands are available to enable straight
lines, arcs and circles to be drawn simply - see GRAPHICS in
Section W3.
The INPUT statement has additional features and
instructions. READ, DATA and RESTORE are added - see
below: PUTTING DATA INTO PROGRAMS.
On the Spectrum it is possible to define your own numeric and
string functions in а program -see USER DEFINED
FUNCTIONS below.
The Spectrum operates in a ‘fast mode’ at all times and is
roughly four times faster than the ZX81.
Multiple statements on a line are possible on the Spectrum
with a colon(:) as a statement separator. For example:
10 LETX-4:LETY26: LET Z=8
Whilst this is a useful addition, multiple line statements can
also be very confusing and their use should be minimised. This
said, they can be useful for additional REM statements,
assignments of related variables and conditional program
sequences, and for the combination of graphics and colour
commands.
457
The facility of being able to place a sequence of instructions
after a conditional test is valuable. The sequence of BASIC
Instructions following an IF...THEN will be executed IF the
condition is TRUE. Control passes directly to the next line of
the program if the condition is false. We can write:
10 INPUT å
20 IF а<1 OR a>9 THEN PRINT “Out of Range’’:
GOTO 10
30 PRINT a
It is important to remember that you can only GOTO a line
number and start at the beginning of that line. You cannot
access the second or subsequent statements of a line with
multiple statements.
(xii) There is no SCROLL key on the Spectrum, but scrolling is
done automatically by pressing any key (except N, STOP,
BREAK) when ‘Scroll?’ appears on the screen. Making the
Spectrum SCROLL in the same way as the ZX81 SCROLL
command has been covered in the text.
(xiii) It is important to note that CLEAR operates differently on the
Spectrum than on the ZX81. CLEAR not only erases all
variables in memory, but also resets RAMTOP апа
RESTORE s as well as clearing the GOSUB stack. In fact you
can use CLEAR on the Spectrum to reserve protected memory
space above RAM TOP: using a command like CLEAR 23800
sets RAMTOP to 23800. This cannot be done on the ZX81.
You have seen the modifications required for the ZX81 programs to
run on the Spectrum. Here is a summary for reference, to convert any
programs you may come across in books or magazines. All programs in
the text and the program library (Appendix VI) are annotated with any
required Spectrum changes.
ZX81 TO SPECTRUM PROGRAM CONVERSION
There are relatively few things to bear in mind when converting a
ZX81 program for the Spectrum. Of course, the ZX81 will not have
included colour or sound in the programs, and these are aspects you
can add for yourself. Note that ZX81 programs SAV Ed on cassette will
not load into the Spectrum, even if no ZX81 specific commands have
been used.
Perhaps the first thing to note is that you must be in CAPS mode to
produce listings and programs which are identical to those of the
ZX81. (Use CAPS SHIFT with CAPS LOCK to stay in this mode
when you switch on.)
PLOT plots in high resolution — 256 x 176 pixels — whereas on the
ZX81 the resolution was only 64 x 44. Thus as a general rule you сап
458
simply multiply by a factor of four to any PLOTted points in a ZX81
program to obtain a working Spectrum version. Hence PLOT 4,10 on
the ZX81 becomes PLOT 16,40 on the Spectrum.
The Spectrum has no FAST and SLOW modes, as it runs in the
equivalent of the SLOW mode all the time (always a screen display)
but at the speed of a fast mode. Just omit program lines that contain
the instructions FAST or SLOW.
The Spectrum does not have SCROLL as a program instruction as
the ZX81 does. To SCROLL the screen in a Spectrum program you
need to POKE the location 23692 with a number greater than 1, or
with —1. This temporarily disables the ‘SCROLL?’ request, and
when followed by PRINTing AT the last line (line 21) on the screen the
display will SCROLL.
Thus the ZX81 line:
200 SCROLL
is replaced by
200 POKE 23692, – 1 : PRINT AT 21,0;
Raising a number to a power on the ZX81 uses the symbol ‘**’
whereas on the Spectrum we use ‘ ^". RAND іп ZX81 programs is
that instruction on the Spectrum keyboard, but prints as
RANDOMISE.
POK Eing to the display file cannot be easily done, and the same is
true of PEEK used to identify a character on the screen. To get around
this we recommend using PRINT AT instead of POKEing the display,
and SCREENS to replace PEEKing the display. Hence you will have
to calculate what character cell position corresponds to any address in
the ZX81's display file which is used in a program. Read the
description of the ZX81 display file in Unit Q4 in order to find out how
to do this.
PEEKing the character table in RAM is done equally simply on the
Spectrum, with the start of the character table being given by the
following PEEKs, plus 256:
PEEK 23606 + 256* PEEK 23607
This is usually set at 15360 — but you can POKE these addresses and
change the location at which the character table starts in memory. You
can therefore create an entirely new character set in RAM and have the
CHARS variable (stored in the locations above) point to 256 bytes
below it. All other system variables on the ZX81 have equivalents on
the Spectrum. This text has the system variables for both machines
listed in Appendix V.
Because of the amount of memory (6.5k) taken up for graphics on
the Spectrum, you will find that a large program for the 16k ZX81 (of
10k or so), will not fit into a 16k Spectrum. 48k Spectrum owners will
of course have no problems with this, but if contemplating keying in a
459
long program with the smaller machine it is worth making a crude
estimate of the program length, if the information is not given in the
documentation. The number oflines in the listing (total, not numbered
lines only), multiplied by 15 will give you a reasonable estimate (biased
on the high side) of the program length in bytes.
We will now go on to cover the additional Spectrum facilities and
functions, other than those connected with Colour, Graphics and
Sound, which are treated in Unit W3.
TAPE STORAGE
New keywords: VERIFY and MERGE.
Associated new keywords: LINE, DATA, SCREEN$
(1)
SAVING Information on Tape
The SAVE key is used to save information on tape. This can be:
(a) program and variables, (b) arrays, (c) bytes of memory
(memory contents)
When saving information on tape it is essential that the EAR piece jack-
plug 15 removed from the tape recorder.
(a) Programs and Variables
SAVE ‘‘filnam’’ - saves programs and variables.
SAVE ''filnam" LINE 10- saves programs and variables
and when loaded next automatically runs itself from the given
line number.
(b) Arrays
SAVE “alpha” DATA а()- вауев the numeric array а
specified under the name alpha.
SAVE “beta” DATA b$()-saves the string array b$
specified under the name beta.
(c) Bytes
SAVE “gamma” CODE 16384, 6912- saves the bytes
specified. The first figure (in this case 16384) is the address of the
first byte to be saved and the second figure (in this case 6912) is
the number of bytes to be saved.
The particular bytes specified above will save the ГУ picture,
but a special key SCREENS is available to do this:
SAVE ‘‘gamma’’ SCREEN$
460
(i1)
(iii)
VERIFICATION of Information on Tape
The VERIFY key is used to check the information saved on the
tape against the information in the computer.
VERIFY ‘‘filnam’’ - checks programs and variables
VERIFY “аірһа” DATA a()-checks numeric array
specified
VERIFY “beta” DATA b$()-— checks string array specified
VERIFY “сапта” CODE 16384, 6912 – checks bytes
specified (first number – address of first byte, second
number - number of bytes).
LOADING Information from Tape
The LOAD key is used to load new information from the tape,
deleting any old information in the memory.
LOAD ''filnam'' -loads program and variables specified
(and automatically runs the program if the SAVE and LINE
instructions were used to save the program).
LOAD “alpha” DATA a() - loads numeric array specified by
alpha as array a in memory.
LOAD “Бега” DATA b$() - loads string array specified by
beta as array b$ in memory.
(N.B. If insufficient memory is available, an error message
occurs and the old information in memory is not deleted.)
LOAD “сатта” CODE 16384, 6912 loads the bytes specified (first
number is the address of the first byte, second number is the number of
bytes).
LOAD “gamma” SCREENS is an alternative for the particular
bytes specified above which contain the TV picture.
(iv)
MERGING Programs
The MERGE key is used to combine a program already in
memory with a program on tape (it may not be used on arrays or
bytes).
MERGE ‘‘delta’’ — adds the program delta (stored on tape) to
the program already in memory, overwriting any program lines
and variables in memory which are at the same line numbers or
have the same variable name as those on tape. For example:
Program in memory:
10 PRINT “hello”
20 PRINT
30 PRINT ‘‘goodbye’’
40 PRINT
50 PRINT “ела”
461
Program ‘‘delta’’ on tape:
19 PRINT "no"
20 PRINT “уез”
60 PRINT ‘‘repeat’’
MERGE “delta” results in the program:
10 PRINT “по”
20 PRINT “yes”
30 PRINT ''goodbye"
40 PRINT
50 PRINT “епа”
60 PRINT ‘‘repeat’’
Note the restriction on the use of MERGE. It can only be used for
numbered program lines. These can have defined arrays or variables
that are transferred with the program, but direct data (array values or
bytes) is not MERGEable. See Units T11 and T12 for storing data,
and remember that as long as there is one program line, MERGE will
work.
PUTTING DATA INTO PROGRAMS
New keywords: READ, RESTORE and DATA
Extended function for INPUT key
(1 INPUT Statement
10 INPUT A$ allows input of one string
20 INPUT A,B,C,D allows input of four
numbers
30 INPUT ‘‘Enter your name’’, N$ allows the part within
inverted commas to be
printed at the bottom of
the screen.
If we key in:
10 LET M$ =‘‘SPECTRUM’’
20 INPUT (‘‘I am’’;m$;‘‘.’’); ‘‘Your name?’’, y$
these two lines will produce at the bottom of the screen: I am
SPECTRUM. Your name? “ cursor ”
It is also possible to use INPUT AT in a similar way to
PRINT AT:
10 DIM a$(5)
20 INPUT АТ 0,0; a$(1); АТ 1,0; a$(2); AT 2,0; a$(3); АТ
3,0; a$(4); АТ 4,0; а%(5).
462
(11)
(iii)
This will result in the inputs being placed on separate lines (note
what these co-ordinates mean). The lower part of the screen will
move up to allow all input lines to be on screen. (The upper part
remains unaltered until the lower part would start to write on the
same line — the upper part then starts to scroll.)
10 INPUT LINE a$ allows input of a string without the
computer inserting quotes around the
cursor.
READ and DA TA
These keys allow data to be stored internally within the
program. For example:
10 READ a,b,c
20 PRINT a,b,c
30 DATA 10,20,30
The computer looks at all lines containing DATA statements
and puts them sequentially into a data bank. A pointer is
associated with the data bank and is initially set to the first item.
10 20 30
^
When the program reaches a line with a READ statement, the
first data item is allocated to the variable (i.e. a = 10) and the
pointer moves to the second item and so on. So b = 20 and
c= 30.
Note (i) DATA items are separated by commas
(1) variables in READ statements are separated by
commas
(ii) string data items must be in inverted commas
For example:
10 READ a$,b,c$,d
20 PRINT a$,b,c$,d
30 DATA ‘‘smith’’, 90
40 DATA ‘‘jones’’, 60
RESTORE
The RESTORE statement may be used to alter the position of
the pointer. For example:
10 READ a$,b
20 RESTORE
30 READ c$,d
463
40 PRINT a$,b,c$,d
50 DATA ‘‘smith’’, 90, ‘‘jones’’, 60
The effect of line 20 is to reset the pointer to the first item. Thus
a$ = ‘‘smith’’, b = 90, c$ = ‘‘smith’’, d = 90. It is also possible to
use RESTORE with a line number in which case the pointer is
reset to the first item of the data statement of that line (or
following lines). For example:
10 READ a$,b
20 RESTORE 100
30 READ c$,d
40 PRINT a$,b,c$,d
50 DATA ''smith'', 90, ‘‘jones’’, 60
100 DATA ‘‘brown’’, 100, ‘‘white’’, 120
200 DATA ''black'', 8, '*yellow'', 6
This will allocate a$ = “smith”, Ь-90 and c$ = “brown”,
а= 100 (whereas 20 RESTORE gives c$ = smith", d = 90
and 20 RESTORE 200 gives c$ = ‘‘black’’, d = 8).
If CLEAR is used on the Spectrum, it also does a RESTORE
on the data.
USER DEFINED FUNCTIONS
New keywords: DEF FN and FN
The user can define up to 26 numeric and 26 string functions in any
program.
A numeric function is named FN followed by a single letter — e.g.
FN Z.
A string function is named FN followed by a single letter and $ – e.g.
FN A$.
It is necessary to define the function using a DEF FN statement (i.e.
by pressing the DEF FN key). For example:
10 DEF FN а(х)-х%3
20 PRINT FN a(3)
Line 10 defines the function and line 20 would give 3° = 27. For strings:
10 DEF FN q$(a$) = a$ (2 to 6)
20 PRINT FN q$(‘‘harrison’’)
Line 10 defines a string function and line 20 would give ‘arris’.
You may also use functions with several variables:
464
5 LET a=10: LET b= 20
10 DEF FN p(x,y,z) =а*хфћ 2 +ЬЪ*ућ 2+2
20 PRINT FN p(1,2,3)
30 PRINT
40 PRINT FN p(3,2,1)
Note that any constants occurring (in this case a,b) are not included in
the FN; only the variable values are specified (in this case x, y and z).
Thus line 20 gives 93 and line 40 gives 171.
CHARACTER SET AND USER DEFINED GRAPHICS
(1) Character Set
The character set consists of 256 characters each having a code
between @ and 255. The set consists of:
Control characters (code 0 to 31)
ASCII characters (plus the non-standard £ and ©)
Spectrum graphics symbols
User-defined graphics
The program given below will print out the complete character
set (excluding the control characters):
10 FOR n=32 ТО 255: PRINT CHR$ n;: NEXT n
(ii) User defined graphics
These are the letters A to U in graphics mode. They initially
print as these letters (in capitals), until defined. They enable one
to print a given shape in a character cell by pressing a single key.
EXAMPLE: Fill the screen with dogs. Begin by producing a
dog shape which fills a character cell when GRAPHICS D is
pressed and then display the dogs across the screen.
(1) Fill in appropriate squares in 8 by 8 cell
(11) Allow 1 for ink, 0 for paper
(ui) Put appropriate numbers in data statements
Binary Decimal
жа жк l l ` dx 11100001 225
11100010 226
11111100 252
00111100 60
00111100 60
00111100 60
00100100 36
00100100 36
465
со PORE USR 2 2 Ж
Se NEXT n _ (:
то DATA 25,226, 252,52, Ба, еб, З
Б ЗР
-- z | p
20 REM screenfFut of dogs
эр BORDER а: POPER 2: INK е: LC
LS
ip FOR ісе TO ге STEF 2
лла FOR c=@ ТО за STEP =
15а PRINT BT ipi
130 NEXT с
142 NEXT £
The BIN key allows you to enter binary numbers —1.e. BIN
11100001 is equivalent to 225 in the DATA statement (line 65).
The plot of the user-defined graphic in the 8 x 8 grid, expressed
in binary form, can thus be centred directly with the use of BIN
into the DATA statement:
70 DATA BIN 11100001, BIN 11100010, etc.
OTHER KEYS
The following keys will only operate when the Sinclair microdrive and
the RS 232 (standard printer) interface become available:
OPEN ж, CLOSE * , MOVE, ERASE, CAT and FORMAT.
The keys IN and OUT are associated with I/O ports (input and output
ports) and enable the SPECTRUM to communicate with peripheral
devices. The equivalent commands used by the operating system run
the ZX Printer. They are beyond the scope of the present text. The use
and format of these instructions will be specified in the documentation
of any equipment using them.
W3: Colour, Graphics and Sound
COLOUR
(i) BORDER AND PAPER
The screen is divided into two areas referred to as:
BORDER (the outer part) and PAPER (the central area). (24
lines of 32 characters.)
The instructions BORDER and PAPER are used to define the
colours of the areas.
The following colours are available:
) black
1 blue
466
(11)
red
magenta
green
cyan
yellow
white
-] OQ) ол © h2
Magenta is a purple colour, and cyan is light blue.
Unless otherwise specified, both BORDER and PAPER are
white. The colour of border and paper can be changed to any of
the eight normal colours. For example:
BORDER 4: the border becomes green on pressing the
ENTER key
PAPER 2: no change occurs on pressing the ENTER
key (it merely cancels PAPER command
already existing). Press the ENTER key
again and the centre becomes red.
(On a black and white ТУ the above numbers correspond to
the order of brightness).
Both instructions can be used in programs:
10 BORDER 2: PAPER 6
These are global commands defining the whole border and
paper areas. PAPER may be used as a specific command (see
below).
PICTURE
The picture area affected by the global PAPER instruction
consists of 24 lines each of 32 positions, i.e. 24 x 32 = 768
character cells. The screen that can normally be printed to is 22
lines of 32 character cells. The character cells have printing
characteristics (attributes) which may be specified.
Each character cell consists of 8 x 8 dots and has two colours
associated with it:
INK (foreground colour)
PAPER (background colour)
Normally each character cell has black ink and white paper.
In addition, each character cell also has а brightness
attributed with BRIGHT (normal ог extra-bright) cor-
responding to BRIGHT 0 and BRIGHT 1 and the attribute
FLASH with the possibility of no-flash or flash corresponding to
FLASH 0 and FLASH 1. For example:
10 PAPER3:INK6: BRIGHT 0 : FLASH 1
would result in background magenta, foreground yellow,
normal brightness and flashing. Flashing characters alternate
467
(111)
the ink and paper colours. In addition, 8 can be used with all
four statements meaning transparent (i.e. left as previous); 9
can be used with PAPER and INK meaning contrast. PAPER
will be dark (black) if INK 15 specified as a light colour (colours 0
to 3), light (white) if INK specified as a dark colour (colours 4 to
7). INK produces contrasting PAPER in the same way.
INVERSE, OVER AND ATTR
The statements INVERSE and OVER may also be used to
control the dot pattern printed in the character cells.
inverse or normal i.e. INVERSE 1 (inverse video) or
INVERSE 0 (normal video)
over or normal i.e. OVER 1 (overprints the new
character on top of the old)
OVER 0 (normal)
All the statements in (11) and (iii) may be used in conjunction
with PRINT and INPUT commands and also with graphics
commands such as PLOT and DRAW. For example:
10 INPUT INK 2; FLASH 1; ‘‘What is your name?’’; N$
20 PRINT PAPER 6; N$
which will result when run in ‘What is your name?’ flashing in
red and white and the name input (in black and white) is then
printed out in black on yellow. If not specified, the PAPER
instruction assumes the contrasting INK, FLASH @ and
BRIGHT 0.
The attributes of any character cell (i.e. PAPER, INK,
BRIGHT and FLASH) on the screen may be determined using
the ATTR key, which returns a number made up as follows:
FLASH on (128), normal (0) +
BRIGHT on (64), normal (Ø) +
PAPER (8* colour) +
INK (colour)
Thus, 10 PRINT ATTR (19,20) would give the number 162 if
the character cell at (19,20) is flashing (128), normal (0), green
paper (32) and cyan ink (2).
The TRUE VIDEO instruction gives the INK colour on
PAPER colour background. This may be changed to
INV.VIDEO (PAPER colour on INK colour). All succeeding
printed character squares have the attributes shifted as if
INVERSE had been used.
468
EXAMPLE 1
This is a simple program to display the colours available and to show
the effect of the transparency and contrast commands.
5 REM colours
10 FOR п-1 TO 22: FOR p=0 TO 7
20 PAPER P: PRINT " е;
30 МЕХТ р: МЕХТ п
40 PAUSE 100
45 REM transparency апа contra
st
50 INK 9: PAPER 6: PRINT AT 0,
0;
60 FOR n=l TO 66: PRINT "colou
rings";: NEXT D: PRINT
70 PAPER 7: INK 0: BRIGHT @
80 PAUSE 100
EXAMPLE 2
This is a simple program drawing coloured straight lines with different
separations.
Line 30 - gives а black border.
Line 320 – gives paper and ink colours (selected at random,
excluding black and white).
Line 200 - resets paper and border to white, ink to black for listing
etc. after program has been run.
Notice how colours are character cell dependent not pixel dependent.
This program clearly shows this effect.
38 BORDER @
40 FOR х-й ТО 254 STEP 2
50 PLOT 128,88: DRAW -127+x,-8
7
60 NEXT x
65 GO SUB 300
76 FOR y=0 TO 174 STEP 3
88 PLOT 128,88: DRAW 127,-87+y
90 NEXT y
95 GO SUB 300
100 FOR z=0 ТО 254 STEP 2
110 PLOT 128,88: DRAW 127-z,87
120 NEXT Z
125 GO SUB 300
130 FOR a=0 TO 174 STEP 3
140 PLOT 128,88: DRAW -127,87-a
150 NEXT a
200 PAPER 7: INK 0: BORDER 7
210 STOP
300 LET i=(5*RND+1): LET p-INT
(S*RND)+1
310 IF i=p THEN GO TO 10
320 PAPER p: INK i
330 RETURN
469
GRAPHICS
New keywords: DRAW, CIRCLE, POINT
The screen is 22 lines by 32 columns – i.e. 704 character cells for
graphics use. Each character cell consists of 8 by 8 dots (called pixels).
Thus the pixel co-ordinates go from (0,0) bottom left-hand corner to (255,
175) the top right-hand corner.
Colour Graphics
You can do graphics in colour but remember that the pixels in any
one character cell can only be either of the two colours corresponding to
the current ink and paper values for the character cell.
For example, let’s attempt to draw three circles one black, one blue and
one red:
10 INK 2: CIRCLE 40,40,30 (red circle)
20 INK 1: CIRCLE 60,60,40 (blue circle)
30 INK 0 : CIRCLE 50,50,40 (black circle)
This example shows that colour graphics is possible but can only be
handled with great care. It is important to be clear about character cells
as opposed to pixels. For example, you can draw three circles one black,
one blue and one red:
10 INK 2 : CIRCLE 70,70,70 (red circle)
20 INK 4: CIRCLE 70,70,50 (blue circle)
30 INK 0 : CIRCLE 70,70,30 (black circle)
Graphics Commands
PLOT X.Y — inks in the pixel at the point (X,Y)
DRAW X1,Y1 -inks in the line from the point specified previously to
470
the point X1 pixels to the right and Y1 pixels up from
it. For example:
10 PLOT 20,30 - plots point (20,30)
20 DRAW 50,60 — draws line from point (20,30)
to the point (20 50,30 + 60),
i.e. (70,90).
DRAW Х2,Ү2,А- draws an arc of a circle from the previously spec-
ified point to the point X2 pixels to the right and
Y2 pixels up from it with an angle A radians
(anticlockwise). For example:
10 PLOT 30,30
20 DRAW 60,60
30 DRAW 80,80, PI
CIRCLE X,Y,A draws a circle centre (X,Y) and radius A
POINT (X,Y) will give @ if pixel at (X,Y) is paper colour and 1 if ink.
For example:
10 CIRCLE 40,40,30 - draws circle centre (40,40) and radius 30
20 PRINT POINT (40,40)- pixel paper - 0
30 PRINT POINT (70,70)- pixel ink - 1
The commands INVERSE and OVER may be used with the graphics
commands. For example:
PLOT INVERSE 1 wil put paper colour at pixel
PLOT OVER 1 will change ink to paper at pixel
There is no UNPLOT on the Spectrum. We must use INVERSE or
OVER. PLOT OVER 1 or PLOT INVERSE 1 effectively unplot the
pixel. DRAW OVER 1 may be used to rubout a line while preserving
the original information; compare result of program 1 with that of
program 2.
18 FOR п-1 IO 22
2@ PRINT
за NEXT n
ге PLOT @,@: DRAN 255,175
435 STOF
оа PLOT @,@: BRAW INVERSE 1; 25
2,175
ла FOR n= =1 TO 22
за PLOT @,@: DRAW INVERSE i:25
5,125 Е š w
Try this one-line program:
10 PLOT 65,27: DRAW OVER 1; 120,120,49*3*PI
Try different values in place of 49.
EXAMPLES
1 Use of PLOT and DRAW commands (straight lines)
This program makes use of these statements to draw a histogram
by drawing a series of rectangles.
Lines 70 and 80 produce a rectangle as shown:
- W
x, yo
10 REM Histogram using DRAW
20 READ х0,у0: LET x=x@
25 REM Coordinates of LHS
30 READ w,n
35 REM Width and number of uni
ts
40 FOR j=1 TO n
50 READ h
60 REM Unit height
70 PLOT x,y0
80 DRAW м,0: DRAW @,h: DRAW -w
,9: DRAW 0,-П
90 LET x=x+w
100 NEXT 1
105 DATA 5,5,20,12
110 DATA 12,45,67,98,134,167,17
0,136,124,87,46,20
472
2 Use of DRAW command (arcs of circles)
This program produces a pattern by drawing four sets of
semicircles. The basic plotting line is illustrated by the diagram
of the effect of line 40. This is repeated within a series of four
loops.
п.
-бӨха а
10 LET a=0
20 FOR n=129 TO 254 STEP 3
30 LET а=а+1
40 PLOT n,0: DRAW -6*a,0,PI
50 NEXT n
60 LET b=
76 FOR n=129 TO 254 STEP 3
80 LET b=b+l
90 PLOT n,175: DRAW -6*b,@,-PI
100 NEXT n
110 LET c=0
120 FOR п-90 ТО 174 STEP 3
130 LET с=с+1
140 PLOT 0,п: DRAW 0,-5%с,-РІ
150 NEXT n
160 LET d=0
176 FOR n=90 TO 174 STEP 3
180 LET d=d+l
190 PLOT 255,n: DRAW @,-6*d,PI
200 NEXT n
und VN
Akaros tirga
25840471515,
қосулы Ту
=
УЫ,
“4 a. ы % 4
ЖАЗАСЫ
NN М У NN
Г] тҮ a -—"" T
МУМ z ==
N m LS m mh 5
x ay 5 4 Ux 1 VANY š “ ? i %
52) 25 ENO
ORE WOW Arita
Aadi Eek ^ n Te
«саг ШЕН t EPLET Pe ESL
rigat Al . 45
patatie И * Не
азга БИН I NW D BI
quati, 27777 ji ИР 1 $A;
473
Try inserting the following lines to see the effect of colour (note
graphics is pixel but colour is character cells).
5 INK 2
55 INK 5
105 INK 6
155 INK 3
Use of CIRCLE command
This command draws a circle and by varying the position of the
centre and the radius of the circle we can obtain an acceptable
drawing of a cone:
5 REM Draw a cone
10 READ i,p,b
15 REM ink,paper,border
20 READ cr
25 REM radius of cone
30 CLS : INK i: BORDER b: PAPE
Кр: CLS
40 LET x-50
50 FOR r=cr TO 1 STEP -1
60 CIRCLE х,90,г
70 LET x=x+3
80 NEXT r
90 DATA 1,4,6
100 DATA 50,3
4 Use of user-defined functions for graph plotting
The program below illustrates the use of the DEF FN and FN
instructions in plotting graphs. Line 5 defines the function. Line
10 bypasses the subroutines (lines 20 to 100) and the main
program first defines a=5 (line 120), then calls the first plot
subroutine (lines 20 to 50), which uses a loop to define values of
x. Line 30 makes the variable b equal to COS x and passes
control to the subroutine at line 200 to evaluate y using the FN
(y) instruction in line 200. Note this is a nested subroutine. Line
210 plots the results with suitable scale factors. On return to the
subroutine the next value of x is taken and the process repeated.
On return to the main program, the second subroutine, lines 70
to 100, is called, to plot the SIN x function by making b = SIN x.
The variable a is redefined to equal 15 in line 150 on
completion of the first two plots, and the subroutines are called
474
In sequence again. Note the capability to define a function using
variables, and then define the values of the variables as
appropriate. In this case, two values (COSx and SINx) are given
to b, and the amplitude a is defined as first 5, then 15. Four plots
are produced from the one user-defined function of line 5.
> DEF ҒЫ чіхі-ьға
120
2 ее то
15 REM #xFUNCTION ONE PLOT жж
ек *£*+SUBRGUT INE жж
20 FOR x=@ ТО 25 STEP .1
Зе LET b-COS x: GO SUB >
SS REH xxEND FN ONE 3135 жж
+++» X X <£ < kX x < ЖЖ
26
d
Sa REM ##FUNCTION TUO PLOT zx
= #X SUBROUTINE жж
1@5 НЕН xxEND FN THO Svs жж
+++ ++ ++ X 2 3 x £ ЖЖЖ
110 БЕН #+#+++ ++ +++ kE x #5 5+ + + x= +
жүнін PROGRAM жж
17@ GO SUB 7о
180 STOP
185 REM ##END MAIN PROGRAMS
$ £ x 3 X X X X X X X x x 3 35 £ £ £ x =
19а REH ЖӘМШБВКБООТІМЕ-СЕН САТЕ + ж
FUSING FN AND PLOT ex
200 LET u=FN u (x;
210 PLOT x2#1@,yYs#3+56
азге RETURN
230 REM rxzENDSUB FUNCTION USE#+
SREFES TEESE ЕЕЕ ЕЕ ET EF FFE
SOUND
New keyword: BEEP
BEEP 6, 2 produces a note of duration 6 seconds and a pitch 2 semitones
above middle C. The sound is fairly quiet; however fractional changes
in pitch are available and it is possible to tune it to different
instruments. To obtain the even-tempered scale of C major:
BEEP 1,0 : BEEP 1,2: BEEP 1,4 : BEEP 1,5: BEEP 1,7:
BEEP 1,9 : BEEP 1,11 : BEEP 1,12
475
The short program below gives some idea of the useful musical range
and how it may be used for sound effects.
5 REM MusicaLl ranae
30 RERD pPil,Pzz
15 REM lowest and highest freq
го FOR п=рӣ TO pz
=e BEEP ,5,п
ар PRINT AT (i13-n»;353,inei-21
со NEXT n
55 DATA -25,308
Ба PAUSE 200: CLS
70 REM $0 — effect
ва LET х-.1 E
aa FOR N-60 TO 20 STER 73.
SS PRINT AT i380-n.23?.22.
100 BEEP .@5,n
130 LET x=x =
De NEXT n ie
іза BEEP .05,-25: EEEF .1,50
476
APPENDIX I
ZX81 BASIC Summary
CONVENTIONS
nor m or p
numeric expression
string expression
expression (string or numeric)
variable name
statement
indicates an optional item
indicates a string instruction
Numeric variables are first character a ietter, then any alphanumeric characters.
String variables are À to Z, followed by $.
OPERATING COMMANDS
LOADs
SAVE s
RUN [n]
CLEAR
NEW
STOP
CONT
FAST
SLOW
INPUT/OUTPUT INSTRUCTIONS
INPUT V
INKEY$
LIST [n]
PRINT [ell,e][;e][AT n,m;][TABn;]
CLS
PLOT m,n
UNPLOT m,n
LLIST [n]
LPRINT [el]L,elL;e]l TAB n;]
COPY
OTHER INSTRUCTIONS
POKE n,m
PEEK n
PAUSE n
REM
LET V[$] =e
Load a program from tape. String may be null
(‘*’’) (Loads first program)
Save a program on tape
Run program [starting at line n]
Resets all variables in program
Clears out program and variables
Stops program execution
Starts execution after BREAK or STOP
Screen not displayed until end, PAUSE,
INPUT, SLOW. Computes only.
Screen displayed continuously, whilst
computing
Input numeric or string variable from keyboard
Reads current input character. Does not wait for
key to be pressed.
Displays program [starting from line n]
Print on screen
Clears the screen
Plot % graphic char. | 0< = m< = 63 horizontal
Unplot pixel 0< = n< = 43 vertical
List program on printer [starting from line n]
Print on line printer
Print a copy of screen on printer
Store the value m in memory location n.
O< = m< = 255.
Returns the value stored in memory location n
Halts program for п/50ѕесопаѕ (п/60 in U.S.).
If n>32767 then pauses until key pressed.
(n<65535)
REMARK - comments. Ignored in program
execution.
Assigns the value of e to V
477
DIM У[$] (n[,m])
RAND [n]
RND
GOTO n
GOSUB п
RETURN
IF e THEN <s>
FOR V =n TO m [STEP p]
<s>
[<s>]
NEXT V
TRIG FUNCTIONS
SIN n
COS п
TAN n
ASN n
ACS n
ATN n
NUMERIC FUNCTIONS
EXP n
LN n
SOR n
INT n
ABS n
SGN n
PI (m)
STRING FUNCTIONS
LEN s
CHR$ n
CODE s
STR$ n
VAL s
+
EXPRESSIONS
PRIORITY
12 ()
11 any function
10 жж
9 -в
8 ж
?4
6 +-
5 -,<>,<,>,<«,>-
Dimensions array n by m (numeric), n strings of
length m if string
Random number seed
Function returns a random number n. f = n<1
Transfers control to line n
Go to Subroutine at line n
Return from subroutine to line after last GOSUB
If e is true THEN statement s is done, if e is
false then s is not done. For e see expressions.
Evaluates as TRUE = 1, FALSE = 0
V is any single letter control variable.
m,n,p any numeric expressions. STEP 1 is
assumed if STEP not specified
Increments V by STEP. Goes to next line if
V>m (m2n) or V&m (n2m).
Sine n
Cosine n
Tangent n
Arc Sine n (ARCSIN on keyboard)
Arc Cosine n (ARCCOS on keyboard)
Arc Tangent n (ARCTAN on keyboard)
n evaluated as radians
Exponent n or е"
Log. nor ln n
Square root of n
Integer of n (rounds down)
Absolute value of n
1 if n is positive, 0 if zero, — 1 if negative
3.1415927
Length of string s
Character of code n (single character string)
Code of first character in string s
Convert numeric expression to String
Convert string to numeric expression
String concatenation
bracketed expressions
functions
exponentiation
unary minus
multiplication
division
addition & subtraction
equality & inequality
478
4 NOT
3 AND
2 OR
ZX Spectrum Basic Summary
CONVENTIONS
n, m or p
5
е
V
<s>
[ ]
logical inversion
logical AND
logical OR
numeric expressions
string expression
expression (string or numeric)
variable name
statement
indicates an optional item
Numeric variables are first character a letter then any alphanumeric characters.
String variables are a letter followed by $.
OPERATING COMMANDS
BREAK
CLEAR
CLEAR n
CONT
DELETE
EDIT
ENTER
GRAPHICS
LOAD s
LOAD s CODE n,m
LOAD s DATA V()
MERGE s
NEW
RUN [n]
SAVE s
SAVE s LINE n
SAVE s CODE n,m
SAVE s SCREEN $
SAVE s DATA V()
STOP
VERIFY s
VERIFY s CODE n,m
VERIFY s DATA V()
OTHER INSTRUCTIONS
BIN n
DATA el, ЖЗ,
DEF FN
interrupts operation e.g. execution, printer
clears variables
changes position of RAMTOP
continues execution after BREAK or STOP
allows deletion of character
allows editing of current line
line entered into program
puts into graphics mode
clears program and existing variables and loads
program specified from tape. (string may be ‘‘”’
in which case the first program is loaded)
loads m bytes into memory starting at address n
loads specified array (string or numeric) into
memory
merges program s with the one already in
memory
clears program and variables
runs program [starting at line n]
Saves program and variables on tape
saves program so that a LOAD is automatically
followed by a GOTO n
saves m bytes starting at address n
saves the picture on tape
saved specified array (string or numeric) on tape
stops program execution
verifies that program specified has been saved
on tape
verifies bytes specified have been saved on tape
verifies array specified has been saved on tape
puts binary number n into decimal
separates multiple statements on a line
gives data items within a program
user-defined function definition. It must be
479
FN
DIM V[$](n[,m])
FOR V =n TO m [STEP p]
NEXT V
GOSUB n
RETURN
GOTO n
IF e THEN <s>
IN n
OUT n,m
LET VI$] = е[$]
PAUSE n
PEEK n
POKE n,m
READ У1[$], V2I$], ...
USR n
GRAPHICS
followed by the name (single letter) of the string
or numeric function and the definition - e.g.
FNa(x,y,z)=xP3+y$44+z45
calls up the user-defined function. Arguments
enclosed in brackets — e.g. FNa(3,5,7)
dimensions array V. Numeric arrays of n rows
[and m columns]. String array of n strings each
of length m characters. Multi-dimension arrays
possible
V a single letter, initiates a loop
V a single letter, completes loop
go to subroutine at line n
returns from subroutine to main program
transfers control to line n
executes statement when the condition is met.
(There may be several numeric and logical
conditions)
returns the byte read from I/O port n
writes value m to I/O port n
assigns value e to variable V
makes program wait a specified time (n = 0 waits
for ever, n=1 to 65535 waits n/5@ seconds in
UK and п/60 seconds in US)
returns the value stored in the memory location
n
stores value m in memory location n
allocates variables the values specified in DATA
statements.
calls the machine-code routine starting address n
22 lines with 32 columns available.
Each character cell consists of 8 by 8 pixels.
256 horizontal points and 176 vertical points.
CIRCLE n,m,p
DRAW n,ml,pl
PLOT n,m
POINT (n,m)
COLOURS:
- black
— blue
— red
- magenta
green
— cyan
— yellow
— white
- O: сл > Ó rO в
|
draws а circle centre (n,m) and radius р
draws line [arc] from previous specified point to
a point relative n horizontal and m vertical
[turning through angle p radians (anticlockwise
if p positive)]
Plots a pixel
@< = n< = 255 horizontal
0< = m< = 175 vertical
returns 0 (paper colour) or 1 (ink colour) of the
pixel (n,m)
480
Picture is divided into 768 (24 lines of 32 columns) character cells.
ATTR (n,m)
BORDER n
BRIGHT n
FLASH n
INK n
INVERSE n
OVER n
PAPER n
SOUND
BEEP n,m
INPUT/OUTPUT INSTRUCTIONS
CLS
COPY
INKEY$
INPUT VI$]
INPUT LINE V$
LIST [n]
LLIST [n]
LPRINT [е][,е][;е]ГТАВ n]
PRINT [elL,el[;elLATp,ml][ TAB m]
TRIG FUNCTIONS
ACS n
ASN n
ATN n
COS n
SIN n
TAN n
(n evaluated in radians)
NUMERIC FUNCTIONS
ABS n
EXP n
INT n
gives colour attributes of the character cell (n, m)
@< = n< = 23 lines
0< = m< = 31 columns
makes border specified colour (n = 0 to 7)
controls brightness (n = 0 normal, п = 1 bright,
n = 8 transparent)
controls flashing (n = 0 normal, п = 1 flash, п = 8
no change)
makes ink (foreground) specified colour (n = 0 to
7, n=8 transparent, n = 9 contrast)
controls dot pattern (п= 0 normal, n=1
inverse)
controls overprinting (п= 0 normal, n=1
mixing)
makes paper (background) specified colour
(n = to 7, n = 8 transparent, n = 9 contrast)
produces sound of duration n seconds and pitch
m semitones above (or below) Middle C.
clears the screen
prints out copy of screen on the printer
reads current input character. Does not wait for
key to be pressed.
input numeric [or string] variable from
keyboard
allows string variable to be input without quotes
displays program [starting from line n]
lists program on printer [starting from line n]
prints out on line printer
prints on screen
22 lines @© = p< = 21
32 columns 0< = т< = 31
Arc cosine п
Arc sine n
Arc tangent n
Cosine n
Sine n
Tangent n
absolute value of n
exponential n (i.e. e")
integer of n (rounds down)
481
LN ñ
PI
RAND [n]
RND
SGN n
SOR n
STRING FUNCTIONS
CHR$ п
CODE s
LEN s
STR$ n
VAL s
VALS s
natural logarithm of n (i.e. log n or In n)
n, 3.1415927
random number seed
function returns a random number between 0
and 1
returns 1 if n is positive, 0 if zero, — 1 if negative
square root of n
character of code n
code of first character of string s
returns length of string s
converts numeric expression into string
converts string expression into numeric
converts s to a string expression (strips off
quotes)
PRIORITY see table for ZX81.
482
APPENDIX II
ZX81 Error Codes
Code Meaning
0
Successful completion, or jump to line number
bigger than any existing. A report with code @ does
not change the line number used by CONT.
The control variable does not exist (has not been set
up by a FOR statement) but there is an ordinary
variable with the same name.
An undefined variable has been used.
For a simple variable this will happen if the variable
is used before it has been assigned to in a LET
statement.
For a subscripted array variable it will happen if the
variable is used before it has been dimensioned in a
DIM statement.
For a control variable this will happen if the variable
is used before it has been set up as a control variable
in a FOR statement, when there is no ordinary
simple variable with the same name.
For a numeric INPUT, will occur if non-numeric
input received.
Subscript out of range.
If the subscript is negative, or bigger than 65535
then error B will result.
Not enough room in memory. Note that the line
number in the report (after the /) may be incomplete
on the screen, because of the shortage of memory:
for instance, 4/20 may appear as 4/2.
No more room on the screen. CONT will make
room by clearing the screen.
Arithmetic overflow: calculations have led to a
number greater than about 10,
No corresponding GOSUB for a RETURN
statement.
You have attempted INPUT as a command (not
allowed).
STOP statement executed. CONT will not try to
re-execute the STOP statement, but continues from
next line.
Invalid argument to certain functions.
Integer out of range. When an integer is required,
the floating point argument is rounded to the nearest
integer. If this is outside a suitable range then error
B results.
483
Situations
Any
NEXT
Jumping into a loop.
Any
Subscripted variables
(Lists and arrays)
Substrings
LET, INPUT, DIM,
PRINT, LIST, PLOT,
UNPLOT, FOR,
GOSUB. Sometimes
during function
evaluation.
PRINT, LIST.
Any arithmetic. Division
by zero is common cause.
RETURN. No STOP
statement before
subroutine is common
cause.
INPUT
STOP
SOR, LN, ASN, ACS,
VAL
RUN, RAND, POKE,
DIM, GOTO, GOSUB,
LIST, LLIST, PAUSE,
PLOT, UNPLOT,
CHR$, PEEK, USR
С The text of the (string) argument of VAL does not VAL
form a valid numerical expression.
D (i Program interrupted by BREAK. At the end of any
statement as the program
runs or in LOAD, SAVE,
LPRINT, LLIST or
COPY.
(ii) The INPUT line starts with STOP. INPUT
F . The program name provided is the empty string. SAVE
Spectrum Error Codes
The report has a code number or letter (so that you can refer to the following table), a
brief message explaining what happened and the line number and statement number
within that line where it stopped. (A command is shown as line 0. Within a line,
statement 1 is at the beginning, statement 2 comes after the first colon or THEN, and
so on.)
The behaviour of CONTINUE depends very much on the reports. Normally,
CONTINUE goes to the line and statement specified in the last report, but there are
exceptions with reports 0, 9 and D.
Here is a table showing all the reports. It also tells you in what circumstances the
report can occur.
Code Meaning
0
ОК
Successful completion, ог jump ќо а line number
bigger than any existing. This report does not
change the line and statement jumped to by
CONTINUE.
NEXT without FOR
The control variable does not exist (it has not been
set up by a FOR statement), but there is an ordinary
variable with the same name.
Variable not found
For a simple variable this will happen if the variable
is used before it has been assigned to in a LET,
READ or INPUT statement, loaded from tape or
set up in a FOR statement. For а subscripted
variable it will happen if the variable is used before it
has been dimensioned in a DIM statement or loaded
from tape.
Subscript wrong
A subscript 1s beyond the dimension of the array, or
there are the wrong number of subscripts. If the
subscript is negative or bigger than 65535, then error
B will result.
Out of memory
There is not enough room in the computer for what
you are trying to do. If the computer really seems to
be stuck in this state, you may have to clear out the
command line using DELETE and then delete a
program line or two (with the intention of putting
them back afterwards) to give yourself room to
manoeuvre with — say - CLEAR.
484
Situations
Any
NEXT
Jumping into a loop is a
common cause.
Any
Subscripted variables
(arrays),
Substrings
LET, INPUT, FOR,
DIM, GO SUB, LOAD,
MERGE. Sometimes
during expression
evaluation.
Code Meaning
5
Out of screen
An INPUT statement has tried to generate more
than 23 lines in the lower half of the screen. Also
occurs with PRINT AT 22,...
Number too big
Calculations have led to a number greater than
about 1055.
RETURN without GO SUB
There has been one more RETURN than there were
GO SUB.
End of file
STOP statement
After this, CONTINUE will not repeat the STOP,
but carries on with the statement after, or next line
after, STOP.
Invalid argument
The argument for a function is no good for some
reason.
Integer out of range
When an integer is required, the floating point
argument is rounded to the nearest integer. If this is
outside a suitable range then error B results.
Nonsense in BASIC
The text of the (string) argument does not form a
valid expression.
BREAK - CONT repeats
BREAK was pressed during some peripheral
operation.
The behaviour of CONTINUE after this report is
normal in that it repeats the statement. Compare
with report L.
Out of DATA
You have tried to READ past the end of the DATA
list.
Invalid file name
SAVE with name empty or longer than 10
characters.
No room for line
There is not enough room left in memory to
accommodate the new program line.
STOP in INPUT
Some INPUT data started with STOP, or- for
INPUT LINE - BREAK was pressed.
Unlike the case with report 9, after report H
CONTINUE will behave normally, by repeating the
INPUT statement.
FOR without NEXT
There was a FOR loop to be executed no times (e.g.
FOR n=1 TO 0) and the corresponding NEXT
statement could not be found.
485
Situations
INPUT, PRINT AT
Any arithmetic. Division
by zero is common cause.
RETURN. No STOP
statement before a
subroutine is common.
Microdrive, etc,
operations only.
STOP
SOR, LN, ASN, ACS,
USR (with string
argument)
RUN, RANDOMIZE,
POKE, DIM, GO TO,
GO SUB, LIST, LLIST,
PAUSE, PLOT, CHR$,
PEEK, USR (with
numeric argument)
VAL, VAL$
LOAD, SAVE, VERIFY,
MERGE, LPRINT,
LLIST, COPY. Also
when the computer asks
scroll? and you type
READ
SAVE
Entering a line into the
program
INPUT
FOR
Code Meaning
J
K
Invalid I/O device
Invalid colour
The number specified is not an appropriate value.
BREAK into program
BREAK pressed, this is detected between two
statements. The line and statement number in the
report refer to the statement before BREAK was
pressed, but CONTINUE goes to the statement
after (allowing for any Jumps to be done), so it does
not repeat any statements.
RAMTOP no good
The number specified for RAM TOP. is either too big
or too small.
Statement lost
Jump to a statement that no longer exists.
Invalid stream
FN without DEF
User-defined function
Parameter error
Wrong number of arguments, or one of them is the
wrong type (string instead of number or vice versa).
Tape loading error
A file on tape was found but for some reason could
not be read in, or would not verify.
486
Situations
Microdrive, etc.,
operations only
INK, PAPER,
BORDER, FLASH,
BRIGHT, INVERSE,
OVER; also after one of
the corresponding control
characters
Any
CLEAR; possibly in
RUN
RETURN, NEXT,
CONTINUE
Microdrive, etc,
operations only
FN
FN
VERIFY, LOAD or
MERGE
APPENDIX III
ZX81 Character Codes by Keyboard Arrangement
Note: Character codes for both the ZX81 and the Spectrum are listed in order of code
number in Section P, and an alphabetic list for the Spectrum is included in Unit W-1.
1. KEYBORD CHARACTERS
CHARACTER CODE CHARACTER CODE
PLOT 246 NEW 230
UNPLOT 252 SAVE 248
REM 234 DIM 233
RUN 247 FOR 235
LINE2 RAND 249 LINES GOTO 236
RETURN 254 GOSUB 237
IF 250 LOAD 239
INPUT 238 LIST 240
POKE 244 LET 241
PRINT 245
COPY 255
CLEAR 253
CONT 232
CLS 251
LINE4 SCROLL 231
NEXT 243
PAUSE 242
BREAK —
TOTAL 26 Characters.
May be entered when mode cursor appears.
Obtained by pressing desired key.
2. SHIFT CHARACTERS
CHARACTER CODE CHARACTER CODE
EDIT 117 ж 5 192
AND 218 OR 217
THEN 299 STEP 224
TO 223 <= 219
LINE1 «€ 114 LINE2 <> 221
113 >= 220
À 112 $ 13
> 115 ( 16
GRAPHICS 116 ) 17
RUBOUT 119 es 11
487
CHARACTER CODE CHARACTER CODE
STOP 227 : 14
LPRINT 223 қ 25
SLOW 228 ? 15
FAST 229 / 24
LINE: 3 LLIST 226 LINE4 * 23
“. 216 < 19
- 22 > 18
+ 21 i 26
= 20 £ 12
FUNCTION 121
TOTAL 39 Characters.
Obtained by pressing and keys together.
3. LETTER CHARACTERS
CHARACTER CODE CHARACTER CODE
1 29 А 38
2 30 S 56
3 31 D 41
4 32 F 43
LINE 1 5 33 LINE3 G 44
6 34 H 45
7 35 J 47
8 36 K 48
9 37 L 49
0 28 NEWLINE 118
(ENTER)
о 54 SHIFT
W 60 Z 63
F 49 K 61
R 55 C 40
LINE? Т 57 LINE4 V 59
Y 62 B 39
U 58 N 51
I 46 M 50
O 52 27
Р 53 SPACE 0
TOTAL 39 Characters.
May be entered when mode cursor appears.
Obtained by pressing the desired key.
488
4. GRAPHICS CHARACTERS
CHARACTER CODE CHARACTER CODE
F| 1 ЕЕ 8
[4 2 FS 10
Lal 135 ы 9
а) 4 ЫШ 138
ІЛМЕ 1 u 5 LINE 3 E 137
ыш 131 ES 136
= 3 inverse — 150
. 133 inverse + 149
Inverse = 148
ma 129 inverse : 142
М 130 Inverse ; 153
F 7 Inverse ? 143
LINE 2 = 132 LINE 4 inverse / 152
= 6 Inverse * 151
Fg 134 inverse < 147
inverse $ 141 inverse > 146
Inverse ( 144 Inverse , 154
Inverse ) 145 Inverse £ 140
inverse "' 139
TOTAL 36 Characters.
Entered in mode, obtained by pressing |SHIFT| |GRAPHICS | keys.
Character obtained by pressing [SHIFT] [CHARACTER
5. INVERSE GRAPHICS CHARACTERS
INVERSE INVERSE
CHARACTER ` CODE CHARACTER CODE
1 157 Q 182
2 158 W 188
3 159 E 170
4 160 R 183
LINE 1 5 161 LINE2 Т 185
6 162 Y 190
7 163 U 186
8 164 I 174
9 165 О 180
0 156 P 181
489
INVERSE INVERSE
CHARACTER CODE CHARACTER ` CODE
A 166 Z 191
S 184 x 189
D 169 C 168
F 171 V 187
LINE3 G 172 LINE4 B 167
H 173 N 179
J 175 M 178
K 176 | 155
i, 177 128
(SPACE)
TOTAL 38 Characters.
May be entered in mode obtained by keys.
Obtained by pressing desired keys.
6. FUNCTION CHARACTERS
CHARACTER CODE CHARACTER CODE
SIN 199 LN 205
COS 200 EXP 206
TAN 201 AT 193
INT 207 INKEY$ 65
LINE2 AND 64 LINE4 NOT 215
STR$ 213 n(PI) 66
CHR$ 214
CODE 196
PEEK 211
TAB 194
ARCSIN 202
ARCCOS 203
ARCTAN 204
LINE 3 SGN 209
ABS 210
SOR 208
VAL 197
LEN 198
USR 212
TOTAL 25 Characters.
Мау be entered іп [Е] mode obtained by pressing [ SHIFT |
key.
Characters obtained by pressing desired character key.
The mode operates for only one character input.
490
APPENDIX IV
Use of Cassette Tapes
The following information concerns the use of cassette tapes for program storage and
retrieval. Other details of personal tape library practice can be found in the main text.
1
New tapes: Always ‘fast forward’ and ‘rewind’ a tape completely before use for
program storage. This ensures an even winding and tension. If you have the
patience, running the tape one way in ‘play’ mode after fast forward and reverse is
desirable.
Do not use the first 15 or 20 seconds of any tape. Most tape problems of coating
loss and stretch occur in this portion of the tape.
Always rewind tapes fully after use, so as to not leave tape with program data
exposed. Never touch the surface of the tape. Before inserting a tape in the cassette
player, take up the slack in the tape (using a finger or a pencil) by turning one
drive wheel until the other moves.
Always replace tapes in the correct library boxes immediately after use. Leave the
label side (if only one label) showing.
Tapes with programs meant to be permanent should have the tags removed to
prevent accidental erasure. The holes can always be covered with sticky tape if you
decide in the future to record over a program.
Clean the tape-recorder heads after 2 or 3 hours’ running time with a head cleaner
cassette or head cleaner fluid. De-magnetise heads every 10 or 12 hours’ running.
Leave long gaps (at least 20 seconds) between programs, if more than one program
is on a tape. Note the tape counter readings for beginning and end of each
program. Remember that the tape counter is not highly accurate. You can use the
TV screen to find a gap between programs, watching for the thick black lines of a
program load display change to the thin diagonal lines of a ‘blank tape’ display.
Loading problems. These are notes for the ZX81 user. No problems should be
encountered with the Spectrum in this respect. For each individual ZX81/cassette
system, no problems should be encountered with SAVEing and LOADing
programs with the TONE control set high, and the VOLUME at 3/4 volume. The
characteristics of tape recorders vary somewhat, however, and problems may be
encountered in LOADing programs which have been SAVEd on a different
recorder. Here is a sequence to be followed if a program proves difficult to LOAD.
A Set the TONE control for maximum treble (‘High’).
B Set the VOLUME to about three-quarters of the maximum.
С Rewind tape to the beginning.
D Type: LOAD “A” - i.e. any letter/word except the program name.
Press PLAY on the cassette, then NEWLINE (ENTER) on the 7Х81.
When the thin, slightly sloping black lines change to the programs' typical
thick black and white lines, with approximately equal black and white
bands, with the white crossed by vertical black lines:
(a DECREASE THE VOLUME until this changes back to the THIN
lines.
(b Now INCREASE THE VOLUME, noting where the THICK black
and white program lines eventually seem to become more unsettled
or predominantly black.
Also if you listen to the recording you may be able to notice when the
volume is too high and causes distortion.
E Setthe VOLUME midway between these two points (a) and (b).
Rewind tape.
Type: LOAD “(Тһе program name)”.
Press PLAY on the cassette, then NEWLINE (ENTER) on the ZX81.
If the screen suddenly clears before the program should end, this may
mean volume is still too low.
491
The ZX81 may need to be re-set by pulling out the d.c. supply plug and
re-inserting it if the cursor does not return to the screen, either by itself or
when BREAK is used.
LOAD again, slightly increasing the volume, after rewinding the tape.
If you cannot get a definite, THICK black and white line pattern even at
full volume then your recorder may not be powerful enough to load from
the signal strength on this specific tape. Test this by using another
recorder, or recorder/ZX system. Once the program has LOADed, SAVE
it on to a tape in your own recorder.
Turn off cassette recorder and take the EAR/MIC leads out of the ZX81
before swapping recorders, or else you may cause the system to crash
whilst taking out and re-inserting the plugs.
9 NEVER place a tape on top of the TV monitor. This can affect the signals stored
on the tape because of the electromagnetic field generated by the TV.
492
APPENDIX V
System Variables — ZX81
Notes:
X The system may crash if the variable is poked.
N Poking the variable will have no lasting effect.
S The variable is saved by SAVE.
The number in column 1 is the number of bytes storing the variable. For two bytes,
the first one is the less significant byte. To poke a value M to a two-byte variable at
address N use:
To peek its value, use the expression
Notes
X1
X2
N1
N2
Address
16384
16385
16386
16388
16390
16391
16393
16394
16396
16398
16400
16402
16404
16406
POKE N (M - 256*INT(M/256))
POKE N + 1, INT M/256
PEEK N + 256*PEEK(N + 1)
Name
ERR_NR
FLAGS
ERR_ SP
RAMTOP
MODE
PPC
VERSN
Е PPC
D FILE
DF CC
VARS
DEST
E LINE
CH ADD
Contents
1 less than the report code. Starts off at 255
(for — 1), so PEEK 16384, if it works at all,
gives 255. POKE 16384, N can be used to
force an error halt: N < = 14 gives one of the
usual reports, 15 <=N<=34 or 99
< = N<127 gives an non-standard report,
and 35 < = N < = 98 may disrupt the display
file.
Various flags to control the BASIC system.
Address of first item on machine stack (after
GOSUB returns).
Address of first byte above BASIC system
area. You can poke this to make NEW
reserve space above that area or to fool CLS
into setting up a minimal display file. Poking
RAMTOP has no effect until one of these
two is executed.
Specified K, L, F or G cursor.
Line number of statement currently being
executed. Poking this has no lasting effect
except in the last line of the program.
Q Identifies ZX81 BASIC in saved programs.
Number of current line (with program
cursor).
See Unit O4.
Address of PRINT position in display file.
Can be poked so that PRINT output is sent
elsewhere.
See Unit U2.
Address of variable in assignment.
See Unit U2.
Address of the next character to be
interpreted: the character after the argument
of PEEK, or the NEWLINE (ENTER) at
the end of a POKE statement.
493
16408
16410
16412
16414
16415
16417
16418
16419
16421
16423
16424
16425
16427
16429
16430
16432
16434
16436
16438
16439
16440
16441
16442
16443
16444
16477
16507
X PTR
STKBOT
STKEND
BERG
MEM
not used
DF SZ
5 TOP
LAST K
MARGIN
NXTLIN
OLDPPC
FLAGX
SIRLEN
T ADDR
SEED
FRAMES
COORDS
PR CC
S POSN
CDFLAG
PRBUFF
MEMBOT
not used
Address of the character preceding the §
marker.
See Unit U2.
Calculator's b register.
Address of area used for calculator's
memory. (Usually MEMBOT, but not
always.)
The number of lines (including one blank
line) in the lower part of the screen. See Unit
Q4.
The number of the top program line in
automatic listings.
Shows which keys pressed.
Debounce status of keyboard.
Number of blank lines above or below
picture: 55 in Britain, 31 in America.
Address of next program line to be executed.
Line number to which CONT jumps.
Various flags.
Length of string type
assignment.
Address of next item in syntax table (very
unlikely to be useful).
The seed for RND. This is the variable that
is set by RAND.
Counts the frames displayed on the
television. Bit 15 is 1. Bits @ to 14 are
decremented for each frame sent to the
television. This can be used for timing, but
PAUSE also uses it. PAUSE resets to 0 bit
15, and puts in bits @ to 14 the length of the
pause. When these have been counted down
to zero, the pause stops. If the pause stops
because of a key depression, bit 15 is set to 1
again.
x-coordinate of last point PLOTted.
y-coordinate of last point PLOTted.
Less significant byte of address of next
position for LPRINT to print at (in
PRBUFF).
Column number for PRINT position.
Line number for PRINT position.
Various flags. Bit 7 is on (1) during compute
and display mode.
Printer buffer
NEWLINE).
Calculator memory area; used to store
numbers that cannot conveniently be put on
the calculator stack.
destination in
(33rd character is
494
System Variables — Spectrum
Notes:
X The system may crash if the variable is poked.
N Poking the variable will have no lasting effect.
The number in column 1 is the number of bytes in the variable. For two bytes, the
first one is the less significant byte. To poke a value M to a two-byte variable at address
N use
and to peek its value, use the expression
Address
23552
23560
23561
23562
23563
23565
23566
23568
23606
23608
23609
23610
23611
23612
23613
23615
23617
23618
23620
23621
POKE N(M - 256% INT(M/256))
POKE N + 1, INT M/256
POKE N + 256* PEEK (N + 1)
Name
KSTATE
LAST K
REPDEL
REPPER
DEFADD
K DATA
TVDATA
STRMS
CHARS
RASP
PIP
ERR NR
FLAGS
TV FLAG
ERR SP
LIST SP
MODE
NEWPPC
NSPPC
PCC
Contents
Used in reading the keyboard.
Stores newly pressed key.
Time (іп 50ths of a second - in 60ths of a
second in N. America) that a key must be
held down before it repeats. This starts off at
35, but you can POKE in other values.
Delay (in 50ths of а second - in 60ths of a
second in America) between successive
repeats of a key held down: initially 5.
Address of arguments of user-defined
function if one is being evaluated; otherwise
0.
Stores 2па byte of colour controls entered
from keyboard.
Stores bytes of colour, AT and TAB controls
going to television.
Addresses of channels attached to streams.
256 less than address of character set (which
starts with space and carries on to the
copyright symbol). Normally in ROM, but
you can set up your own in RAM and make
CHARS point to it.
Length of warning buzz.
Length of keyboard click.
1 less than the report code. Starts off at 255
(for - 1) so PEEK 23610 gives 255.
Various flags to control the BASIC system.
Flags associated with the television.
Address of item on machine stack to be used
as error return.
Address of return address from automatic
listing.
Specifies K, L, C, E or G cursor.
Line to be jumped to.
Statement number in line to be jumped to.
Poking first NEWPPC and then NSPPC
forces a jump to a specified statement in a
line.
Line number of statement currently being
executed.
495
Notes
N2
N2
кі ка к ка М)
Address
23623
23624
23625
23627
23629
23631
23633
23635
23637
23639
23641
23643
23645
23647
23649
23651
23653
23655
23656
23658
23659
23660
23662
23664
23665
23666
23668
23670
23672
23675
23677
23678
23679
23680
Name
SUBPPC
BORDCR
E PPC
VARS
DEST
CHANS
CURCHL
PROG
NXTLIN
DATADD
E LINE
K CUR
CH ADD
X PTR
WORKSP
STKBOT
STKEND
BREG
MEM
FLAGS2
DF SZ
S TOP
OLDPPC
OSPCC
FLAGX
STRLEN
T ADDR
SEED
FRAMES
UDG
COORDS
P POSN
PR CC
Contents
Number within line of statement being
executed.
Border colour * 8; also contains the attributes
normally used for the lower half of the
screen.
Number of current line (with program
cursor).
Address of variables.
Address of variable in assignment.
Address of channel data.
Address of information currently being used
for input and output.
Address of BASIC program.
Address of next line of program.
Address of terminator of last DATA item.
Address of command being typed in.
Address of cursor.
Address of the next character to be
interpreted: the character after the argument
of PEEK, or the NEWLINE (ENTER) at
the end of a POKE statement.
Address of the character after the Syntax
error marker.
Address of temporary work space.
Address of bottom of calculator stack.
Address of start of spare space.
Calculator's b register.
Address of area used for calculator's
memory. (Usually MEMBOT, but not
always.)
More flags.
The number of lines (including one blank
line) in the lower part of the screen.
The number of the top program line in
automatic listings.
Line number to which CONTINUE jumps.
Number within line of statement to which
CONTINUE jumps.
Various flags.
Length of
assignment.
Address of next item in syntax table (very
unlikely to be useful).
The seed for RND. This is the variable that
is set by RANDOMIZE.
3 byte (least significant first), frame counter.
Incremented every 1/50th second (U.K.) or
1/60th second (U.S.).
Address of 1st user-defined graphic.
x-coordinate of last point plotted.
y-coordinate of last point plotted.
33-column number of printer position.
Less significant byte of address of next
position for LPRINT to print at (in printer
buffer).
string type destination in
496
Notes
Address
23681
23682
23684
23686
23688
23689
23690
23692
23695
23694
23695
23696
23697
23698
23728
23730
23732
Name
ECHO E
DF CC
DFCCL
S POSN
SPOSNL
SCR CT
ATTR P
MASK P
ATTR T
MASK T
P FLAG
MEMBOT
RAMTOP
P-RAMT
Contents
Not used.
33-column number and 24-line number (in
lower half) of end of input buffer.
Address in display file of PRINT position.
Like DF CC for lower part of screen.
33-column number for PRINT position.
24-line number for PRINT position.
Like S POSN for lower part.
Counts scrolls: it is always 1 more than the
number of scrolls that will be done before
stopping with scroll?
Permanent current colours, etc. (as set up by
colour statements).
Used for transparent colours, etc. Any bit
that is 1 shows that the corresponding
attribute bit is taken not from АТ ТК P, but
from what is already on the screen.
Temporary current colours, etc (as set up by
colour items).
Like MASK P, but temporary.
More flags.
Calculator's memory area; used to store
numbers that cannot conveniently be put on
the calculator stack.
Not used.
Address of last byte of BASIC system area.
Address of last byte of physical RAM.
497
|
a en a E
Е Bd inte Е. BL SANE -
ion wt
Е | т ys - y
rw б» А e ° я Е
* - TIN» Ë "ae © ee et
j* E. g “Hee oa’ 7 90°
та) * gs s тыр “ma =
41 те vv
v vas? dt 27» a Е e" s».
o mE eL = “
ауа B Be
“,.”.-
*(* T i
Tor D
““ “us т game ч © c Z
Е "> 5 9
“p Н & a
e 5
А Р Bn A LIS š - 2 g’
E f LU
Е еу =, E UE Sis
Ae F: og
е. da ^g
s ç =: % J ер с
2 * š 8 4 e
APPENDIX VI
PROGRAM LIBRARY
This appendix contains applications and utility programs and routines, and games.
Some of these have been referred to in the main text. Due to lack of space, the
programs are not fully documented.
1. Polar
Program produces a polar coordinate graph of the function entered as A$. This must be
an expression using A as the dependent variable. Since a common cause of failure of
the VAL function (giving the error code A) on the ZX81 is the exponentiation function,
this is noted and a way of avoiding it given. The angle increment (in radians) is entered
as DA. The appropriate scale factor can be experimented with. If you get a small
cramped plot (or even a single pixel), increase the scale factor. If the plot goes off the
screen, you are informed that the scale factor needs reducing (line 250). Polar
coordinate plots can be thought of as an X,Y plot with the X axis bent into a circle, and
the Y axis plot point defined as a distance R (radius) away from the centre point. Y is
then positioned Бу the COS and SIN functions in lines 190 апа 200.
Spectrum: For use on the Spectrum change ** to À in line 30, and delete line 160.
Change line 70 to read 70 PAUSE 0. In lines 190 апа 200 the centre point must be set
as plot co-ordinates 84, 82, with LET X=84+(R*COS A*SC) and LET
Y = 82 + (R*SIN A * SC). Line 210 must have the limits of X and Y set at 255 and 176
respectively. Line 270 should read PAUSE 0. The program will then run, but you can
also modify it to use the DEF FN and FN instructions: Define the function in line 50,
with a DEF FN a() - SIN A * 3 or whatever the derived function is, and use LET
R = FN a() in line 180. Change the instructions in line 40 to suit.
ле REM “POLAR”
Ба PRINT TAB 8; “4FOLAR ғістат;
TAB а; жж аа ааа”
Зе PRINT ,,"FLOT ROUTINE FOR б
OLAR" , "COORGDINATES ENTER FUMCTI
ON TO^,"BE PLOTTED WITHOUT USE О
Б #4", "(RAISED ТО POWER! FLUMCIIO
M.USE^,"SINsSINsSIN,NMOT SXMsa3,7
OR" “EXAMPLE.USE A FOR ANGLE.“ ,”
YOU MUST ALSO ENTER SCALE “ , "FRc
TGR ANG ANGLE INCREMENT.” -
42 PRINT ,, ENTER EMPRESATON 1
о BE PLOTTED”
S@ INPUT AS
ба PRINT “ENTER ANGLE IMCREMENM
7a INPUT РЯ
aae PRINT “ENTER SCALE ҒОСҒОЭНЭС”
а INPUT 5С
imo СЫЗ
269 КЕМ ЖРБІМТ RAES RHE PLOT
INFORMAT ION +s
i120 FOR F=1 ТО 282
120 PRINT AT 11,Ғ,;”,%”
250 PRINT AT F,28;":”"
142 NEXT F
icd PRINT AT @,32;R3;RT 32,393; “2
.F.2'"; SC; TAB 18; "RMGLE INC. =” ; еЗ
15а FAST
369 REM #ROUND THE CIRCLe, SYES
iFa FOR я-а TO 2xPI STEP OR
i179 REM #EVALUATE FUNCT IQI H
ізе LET R-URL RS
139 REM sNEXT LINES GET J,"
CONVERTED TO POLAR СОБ RM SIM:
COORDINATES, TIMES SCHLE ғостовк,
AND SET WITH CENTRE AT 22 224
290 LET X-204iRxCOS Bs5cCi
200 LET Yz204 iR 351N nasci
210 IF x»60 OR XQ OR Yia OR у
сә THEN сото 252
220 PLOT X,Y
499
=5@ NEXT R
24e сото 292
250 PRINT AT 19,2,’ "OUT оғ BLUT
RANGE. REDUCE SCALE”, “ғастов,”
=68 few NE ‘PRESS B KEY, THEM ЕВР
289 GOTO өе
290 REM #FINISH#
+5.
Set. =; a
ANGLE INC., =, G=
2. Home Accounts
Program allows household expenses for each day for a month to be entered under
various headings, which may of course be changed to suit your needs. Income is
entered, and credits may also be input under any heading. After entries have been
made, a statement of account is derived, which may be printed out. A breakdown of
account by heading can also be printed, and the program and data saved to tape so that
future entries may be added.
The data is stored in string arrays, and these could be increased up to the limits of
memory if a longer period were to be catered for. The program is menu-driven, and all
inputs allow the user to check for errors and re-enter if necessary.
> REM "HOME ACCOUNTS"
10 REM *INITIALISATION*
ZO LET TOTAL=0
ЗО LET I=1
40 LET C=0
50 LET Z$="END "
61 REM жАККАҮ DECLARATION*
е2 DIM D$(3156)
é3 DIM I$(31,1)2
65 DIM АСЗ1›
ее DIM A$C10)
67 DIM (%(631)
ев DIM К%(6315)
&v GOSUB 170
70 REM *MAIN МЕМ
3 CLS
75 PRINT АТ 0%8: "HOME ACCOUNTS
77 PRINT АТ 1%8:"---- --------
80 PRINT АТ 4:10: «MAIN MENU*"
£1 PRINT AT 5%11:"---- ----
500
82 РКІМТ AT 7»2: "А"; АТ 7,103"
TO ADD AN ENTRY"
ӨЗ PRINT АТ 9:2: "5";
FOR ACCOUNT STATEMENT"
84 PRINT АТ 112: "С";
;"FOR CODE BREAKDOWN"
83 PRINT AT 13,2; "X";
;"TO EXIT"
AT 9310:"
AT 11310
AT 13:10
86 PRINT АТ 15%8: "ОРТІОМ 2"
87 INFUT 0%
88 IF 0Ф-"А" THEN GOTO 310
8? IF ü$-"S" THEN GOTO 610
90 IF G$-"C" THEN GOTO 805
100
IF 0%-"Х" THEN STOP
120 PRINT АТ 1538: "UNKNOWN OPTI
ON: "70$
130 PAUSE 100
140 PRINT АТ 15:8;"
150 GOTO 95
160 КЕМ
170 LET
180 LET
190 LET
200 LET
210 LET
215 LET
220 LET
230 LET
240 LET
жж
жж
ЖЖЕХРЕМБЕ CODE
*#INITIALISAT ION
C$cioz"o"
K$(1)="GROCERY"
C$C2)z"P"
{$(2)="PETROL"
C$(s9="C"
K$(3)="CAR REPAIRS“
C$Cc45z"R"
K$(4)="RA TES"
С$%$(5)="М"
250 LET K$(S5)="MISCELLANEQUS"
260 LET C$cé)="I"
270 LET K$(6)="INCOME"
280 RETURN
300 REM #INFUTTING ПАТАж
310 CLS
320 PRINT AT 0:8; "НОМЕ ACCOUNTS
330 PRINT АТ 1:38; "---- --------
350 PRINT АТ 5:57" T
360 PRINT AT 4,2; "ENTER DATE (E
б. 25 NOV: OR PA VEND. ae
FINISH)"
370 INFUT D$(1)
380 IF 0%(1)="" THEN GOTO 370
387 PRINT AT 4927"
386
390
392
)?";
394
395
396
398
IF П%(12-7% THEN GOTO 570
РКІМТ AT 5,5; "DATE: ";D$(1)
PRINT АТ 1035; “СОЕКЕСТ (Y/N
INPUT Q$
IF @$="N" THEN GOTO 250
IF 0% <> "Y" THEN GOTO 394
PRINT AT 10.53"
399 PRINT AT 11557"
501
439
GOSUB 1000
PRINT АТ 16,5; "EXPENSE CODE
INPUT I$CI)
IF I$(I)z"" THEN GOTO 430
GOSUB 2000
» FOR J=1 TO é
IF 1%(12-С%(.1) THEN GOTO 44
NEXT J
PRINT AT 7:95; "UNKNOWN EXFEN
SE CODE: ";I$CID
440
441
442
FAUSE 100
GOTO 410
РКІМТ АТ 739:"EXFENSE CODE:
"PES CJ)
444
)?"
446
447
448
449
460
470
PRINT AT 11:5; "CORRECT (Y/N
INPUT 0%
PRINT AT 11953"
IF @$="N" THEN GOTO 410
IF Q$ <> "Y" THEN GOTO 444
РКІМТ AT 13,53"
PRINT AT 9,9; "AMOUNT (- FOR
EXPENSE) 7"
480
483
487
490
500
22";
510
220
530
932
534
536,
эзе
540
550
560
970
INFUT A$
IF A$="" THEN GOTO 480
PRINT AT 9357"
FRINT AT 9:5; "AMOUNT: “FAG
PRINT AT 13,5; "CORRECT (Y/N
INPLIT Q$
IF Q$="N" THEN GOTO 460
IF 0% 4» "Y" THEN GOTO 510
PRINT AT 12,5; "
PRINT AT 9557"
PRINT AT 7,55"
LET ñ(I)= VAL A$
(ЕТ IsI-*1
LET C=C+1
GOTO 350
PRINT AT 10,3; "00 YOU WISH
ТО SAVE THESE": AT 11,2; "ENTRIES
(Y/N) 7"
575
380
INPUT 0%
IF Q$="N" THEN GOTO 73
589 IF 06 <> "Y" THEN GOTO 575
590
PRINT АТ 10,2;"5ЕТ UP CASSE
TTE RECORDER: WHEN READY PRESS A
NY КЕҰ"
595
596
999
IF ІМКЕҮ% ="" THEN GOTO 595
SAVE “HOME ACCOUNTS"
GOTO 73
600 REM *STATEMENT OF ACCOUNT
902
610 CLS
620 PRINT TAB 5: "ЗТАТЕМЕМТ OF A
CCOUNT"
630 PRINT TAB 5%"-------- -- --
640 PRINT
650 PRINT "DATE": TAB 8% "ТҮРЕ"?
TAB 15: "СК"; TAB 25; "DB"
660 PRINT "eese" TAB Bi "е7
TAB i357 "-<-"3. TAB 257 "=="
670 FOR I=1 TOC
630 PRINT В%(10: TAB 2:1%С12;
690 IF А(12>0 THEN GOTO 720
700 PRINT TAB 25; ABS ACT)
710 GOTO 730
720 PRINT TAB 15;А(1)
730 LET TOTAL=TOTAL+ACI)
740 PRINT
750 NEXT I
793 PRINT TAB 2ОҒ”------ "
755 FRINT "BALANCE"; TAB 20; TOT
766 PRINT AT 2132: "COPY TO PRIN
ТЕК СҮМ) 7"
767 INPUT Q$
768 IF ü$-"N" THEN GOTO 73
769 IF 0% <> "Y" THEN GOTO 767
770 PRINT AT 21,23 "ЗЕТ UP PRINT
ER AND FRESS A KEY"
773 IF INKEY$ ="" THEN GOTO 773
775 PRINT АТ 21927"
780 COFY
790 GOTO 73
S00 REM **BREAKDOUWN OF жж
XACCOUNT BY CODE жж
905 CLS
810 PRINT “STATEMENT OF ACCOUNT
830 PRINT "CODE"; TAB 15% "TOTAL
840 PRINT
250 LET J=1
255 (ЕТ TOTAL=0
860 FOR Ісі TO C
$70 IF I$(I)=C$(J) THEN LET TOT
AL=TOTAL+A(T)
280 NEXT I
990 PRINT K$(J); TAE 15; TOTAL
900 LET J=J+1
910 IF J <= 6 THEN GOTO 855
926 PRINT АТ 2192: "COPY TO PRIN
TER (Y/N? ?"
927 INPUT Q$
928 IF ü$-"N" THEN GOTO 73
929 IF 0% <> "Y" THEN GOTO 927
эзо PRINT AT 21,23 "БЕТ UF PRINT
ER AND FRESS A KEY"
940 IF INKEY$ ="" THEN GOTO 940
503
PIO FRINT AT Z1s27"
veo COPY
990 GOTO 73
1000 REM 33433) )9 9 09 9 ! ) 9 09 X 9 * 99€
X*EXFENSE CODE МЕМІІжж
*#*SUBROUT INE жж
3C EIE ЗЕ ЗЕ ЕЕ ЗЕ ЗЕ ЭЕ ЭЕ ЭЕ ЗЕ ЕЕ EHR
1020 PRINT АТ 7,5;"*ЕХРЕМ5Е CODE
МЕМИ+ :
1090 PRINT AT бұз!” eee m ne
1050 PRINT AT 9*5;"G"; AT 2157"
GROCERY "
1060 PRINT AT 10,93 "Е"; АТ 10,15
т КЕТКЕШ."
1070 PRINT АТ 11:5;"C"3 AT 115915
;"CAR REPAIRS"
1080 PRINT AT 12,5; "Е"; AT 12,15
; "RATES"
1090 PRINT AT 12:5;:"M": AT 13515
; MISCELLANEOUS"
1100 PRINT AT 14,53 "1"; AT 14515
; "INCOME"
1110 RETLIRN
2000 PRINT AT 16,5;"
2010 PRINT AT 14957" "; АТ 14515
2020 PRINT АТ 13,93" "; AT 13315
2050 PRINT АТ 12957" "; AT 12,15
= d
y
2040 PRINT AT 11,5;" "Ó"; AT 11,15
ә 41
y
2050 PRINT AT 10957" "; AT 10,15
= и
,
2060 PRINT AT 9,9:" "; AT 9?,15;"
2070 PRINT АТ 3.93"
2080 PRINT AT 7,93"
2090 RETURN
3. Resval
Program derives the preferred resistor value (i.e. the closest standard resistance) from
inputs of the voltage and current required in a circuit. From these inputs (in volts and
amps) the actual resistance is calculatead by Ohms Law (R = V/I). This value, rounded
to two significant figures, is then used to calculate the value L, 10 to the power L, being
the multiplier for the resistor value. The values stored in the array X(13), entered as
shown in the first program, are then compared with the calculated resistance. The first
value stored in the array which gives a value greater than R is then used to print out the
preferred value for the component. The current and power using a resistor of this value
are then printed. The user may then choose to run the calculation again with different
inputs until the best solution is achieved. This illustrates the basic principle of
computer-aided design (CAD) of circuits, where the derived theoretical values are
modified to suit the actual components available.
504
The array creation program and data values (of resistors with +10% tolerance) are
given below. This program is then edited out, and RESVAL entered. Alternatives to
storing the data in an array would be to assign each value of the array X with a LET
statement, or, if using a Spectrum, to place the values in a DATA statement. Both
these methods would eliminate the problem of avoiding the use of RUN.
Spectrum: Change ** to ^ in lines 220, 240 апа 270.
Change line 340 to read 340 SAVE ‘‘RESVAL”’ LINE 10
Delete line 350
As noted, the program could be modified to use the DATA and READ
statements. Insert a line 340 with the data as given below, and insert
215 READ X. Change X(N) to X in lines 220 апа 240.
1@ REM ##RESISTOR VALUES INTO
ARRAY * x
20 REM жы ІМЕЗ EDITED GUT RFTE
R ENTRY OF URLUES ==
ЗӨ REH жжТНЕМ RESURL PROGRAM Е
NTERED xx
да DIM X113? ue
50 LPRINT “ARRAY VALUE
60 LPRINT
TO XA. VL oam
ве LPRINT a te TE
зе INPUT X tL.
18090 LPRINT TAB т;хаз
110 NEXT L
ARRAY VALUE
"ТЕГҮ
отын о
$
“
RRMA KKK KX
май a? uà чн
m
0
19 REM xRESURL x
20 PRINT "RESURL"
48 PRIN! "PROGRAM DERIVES PREF
ERRED VALUE"; ТАБ Ө; “OF RESISTOR
FROM INPUT"; TAB ә; “VOLTAGE AND C
URRENT VALUES"
50 PRINT _ >
$09 PRINT “PREFERRED UALULECS STO
RED IN ";THB е; “ARRAY . DD NOT REUN
PROGRAH.USE"'; TRB в; “сото 100."
79 PRINT “SAVE WITH GOTO 340.'
ба PAUSE быб
180 PRINT SYOLTAGE ws
ise PRINT TAB 128;U;" VOLTS"
140 PRINT “CURRENT т”;
160 PRINT TAB 12,;,1;" AMPS”
170 LET R-INT (.Мх106/1) 7100
1500 PRINT
"RD = зан “ACTURL RESISTANCE ";
t's .. H +:
әде LET L=INT (LM Rz2. 303} -1
210 FOR N=1 FO is
220 IF Ri=X (Ы) 108x*x«L THEN СОТО
230 NEXT N
243 LET x=X (N) z10 жж
258 Ре "PREFERRED RESISTOR:
53 >- Ж? . а. C ..
260 PRINT “GIVES CURRENT "; INT
(Uuxl28Q^7X)7100;" AHF
505
27m PRINT "BND “ІМТ iíUxsecÉelg.
ы), „ез. cO атте
232 PRINT
сай PRINT “AGAIN? (У мә ``
see INPUT Q
310 IF @$="N" THEN STGP
320 CLS
330 сото заг
340 SARVE “RESURS
350 GOTO 1@
4. Matmult
Program multiplies two square matrices. À two-dimensional matrix is stored as a two-
dimensional array, with the size input. Matrix multiplication requires the number of
columns in one matrix to be equal to the number of rows in the other. The matrices are
set up as square arrays of equal size in this program, and nonsquare mtrices may be
multiplied by entering 0 for the elements of a row or column which is unused. Users
familiar with matrix arithmetic will be able to derive from this program the routines to
handle other matrix operations. The method involves nested FOR-NEXT loops, in
conjunction with three arrays in this program, the third array holding the resultant
matrix.
Other points to be noted are the input and error routines. The input routine prompts
for inputs by row and column number, and when all elements have been entered the
error check subroutine is called, so that the user can check the whole matrix at once.
This avoids the possibility of confusion over row/column numbers.
REM "MRTHULT'"
REM #BETTER IN FRSTs
> FAST
10 PRINT "2D MATRIX вич T IP ICA
TION", жен ннн ннен + жя +++ ж +++ ++"
20 PRINT AT 3,0; “MULTIPLIES SQ
HARE MATRICES." : AT „А; "TO USE F
OR NONSQUARE MATRICES” , ENTER e
TRIX SIZE ТО ACCOMOLATE”, "ANE ЕМ
TER ZEROES.E.G ТО MULTIPLY", Мг
= 3) ET". = Жы ” 23 әзі %
38 PRINT’ "use NS ps Haters зге
NTERING","1 COLUMN AND i ROW O
REST @.",,,ENTER HATAICES 8
ITN
=a PRUSE 200
се PRINT AT 21,2,” 43EMTER MRI
aa REM 4D INENS TOM ISF 2 оны
RESULT MATRICES+
зе DIM Я(5,53
зап DIM B(5,5)
1210 DIM С(5,5)
128 CLS
іза PRINT "ENTER MATRI” 3°, , ЕРІ
TER @ FOR UNUSED ELEMENTI”
249 FOR F=1 ТО 5
ісе FOR N=1 TO 5
158 sarc AT 21,0; “ROU ";F." со
179 INPUT AIF, м)
50 PRINT AT Ғаз, NxOG-O6,mpmpmifF,Ma
150 NEXT М
2220 NEXT F
210 REM ҰМ IDENTIFIES MATRIA FG
adi SUBROUTINE +
=зё GOSUB See
2590 PRINT "MATRIX 2”
250 FOR Ғ=1 те 2
270 FOR М1
2580 PRINT Ar 317 5%; “ROW “;F; ”7 со
омм ‚м;
239 INPUT ӛсе, м:
39090 PRINT AT Fe3, N#6-6;,8 TF,
506
34g u səə
oo. ыы “MATRIX 1 + MATRIX 2
=1 TO Š
Poe TG 5
` на TO S
404 LET СР, М =C Р. МУ eR iF Li ғы:
+1@ (ЕТ СР, М) SINT (Clr. N} +1E= +
di SLES
428 coon AT ҒұЗ,ыіұб-б; C tF Р
dix
339 mr
450 NE
_ +58 PRINT AT 21.8; "INPUT Cicory
|; RIRUN) OR ECE мб)"
i70 INPUT 2%
IF Z$z"C" THEN COPY
IF Z$="R" THEN RUN
GOTO 786
REM «ERROR SUBROLUTINE:x
HE
PRINT AT $0.0." QRE ALL ENTE
: OR NJ)"
Gl
ШІ
л
Ci
n
4-2,
"zr
GUOJ Go
Hl
БФ
F Бф-“Ү” THEN RETURN
PRINT AT 21.9; "RON нен INT
CT ENTRIES?"
INPUT EN
QR F=1 TO EN
PRINT RT 20, n NS AT zi. 9; F $
21,0; "ERROR “;Ғ; ROW
INPUT R
puri zd 21.7; COLUMN т“
PRINT AT 21.0. R$: 22.8; “E
SEBUT M NUMBER
IF M=1 THEN LET R:!R,Ciz
IF Mz2 THEN LET EiR,.Z;z
PRINT AT ntes Cx#6-6; * E
BRx2.C*5-6,N
NEXT F
PRINT AT 21,0:R$
сото S10
REM #END
Gams
«LO Uf 33 4 co po eat Qc C
т
“.
ew
<..
DU n en em gu cn A C c on Tt cr fl inen enm pe p. eq
mp C d D СД f D FE SiC CO <А
AOS әәболоцоюш бу
ENTER MATRIX 1
ENTER @ FOR UNUSED ELEMENTS
i = 5
3 о e
a ә ә
MATRIX 2
© ә 4
ә a =
a a e
HARTRIX 1 ж MATRIX 2 GIVES: -
e e a32
e а е
о e e
INPUT CICOPY) ,RIRUN: OR E (END
507
5. Fruit
Program simulates a fruit machine. The program allows you to continue playing until
your money runs out (which it will eventually) and you can then ‘‘borrow’’ more.
Points to be noted in the program are the overprinting of a string to simulate the
spinning of the wheels (lines 200 to 230), and the logic used to check wins and amount
(if any) won, in lines 250 and 260. The program loops back from line 290 to line 140
unless the money has all gone.
Spectrum: Change line 60 to read 60 PAUSE 0.
10 REM "FRUIT"
NT 1i rh
зә PRINT "YOU HAVE SAP
BLE.", “EACH ROLL COSTS 10 PENSE.
ай PRINT +anPRVOUTS: = THE Sane
PHYS 10Р"; S:°S THE SAME Ege
s 40P"; TAB SS "ЕХбЕРТ REROMHICH E
SO PRINT ,,"PRESS A HEY TO STA
INKEY S$=""" THEN GOTO 6&8
-
-
14 4 4 CTI
mao
th
Том
Т
Qz
(SS STN P
DM тог гон
# x INITIALISE «PRINT +Q +
mi fui co
3)! 20 P Pm mmm ПІГ ТТІ
HHH x i
EBER; T Б | ;
RINT AT 19.8; 55 5 То £
+
HQ IF INKEYS<¢>°S" THEN GOTO 34
RHEE EEE
Gg
ә 7)
4 2.0010
1
2 REM ##5ЕТ WIN LINE + +
=
LET Bnga"t
1-0 FOR Ғсі ТО 3
162 LET A=INT RND +Ë x +:
179 LET Б%-В%- Ж” +A 18:
155 AME #*SPIN WHEELS%
186 RE
1989 LET fs) pw.
200 FOR к=1 TO 1
210 PRINT AT 9.12;F$i01 TG ©)
220 LET F*$=F$íŠ TO »?«rF&il TO ZS;
230 NEXT F
234 REM
235 REM *##PRINT WIN LINES +
256 REM
249
3:
PRINT AT 9.12: 5$
+
14393 +484425 =
245 REM #xCHECK WIN:
250 LET U-(BE$£(2)zE$
3 3
BS 16 (6) Li (Bs (4) =E $ (63
255 REH AMOUNT BONE £
eod LET C=(.18 AND 15-і) 541 +0 &
4,45 3) 4+(1.8 AND W=S AND БЕШ =”
те LET C$=C$ (1) STARAS (Vet Ciz
\+Сс-.1а)
REH
Y
ңғ.
du
GDG DAG JIC
өпаьовбайь
(i SHOE Se олы
=]
O
D
EL XxCHECH IF SOLVENT +E
RINT RT 3. C$
N Е Cs (Š 9:5 ) >ш.10 THEN
FIOI
F. + +МОМЕҮ SPENT z £
Eri AT 3,.,0;"' xYOU ARE ERU.
TAB ә; “BORRÓ ом £2 TIY OR м!
a Mg
LS
MS="Y"' THEN GOTO әт
INT "BETTER LUCK NEXT ТІМ
G;
s QIU fü FO fO nano TO
:m
POP ж
rho CI Сау
nur
rm
о 990
un
i
508
6. Lissajous
A program to produce the intricate, interesting and delightful patterns, named after the
mathematician who discovered the equation that produces them. You merely enter the
values of A, B and C in response to the prompts and watch the patterns develop.
Spectrum users can generate more complex patterns than ZX81 users, because of the
higher resolution PLOT screen.
Spectrum: Change line 80 to read 80 FOR F = 0 TO 200 STEP 2. This defines the
number of points to be plotted. You can experiment with different values for STEP if
you want more or fewer points plotted. Line 90 needs the two 30s changing to 120, and
line 100 the two 20s changing to 80. A and B can both be input with values up to about
10 on the Spectrum, so change the Input prompts to suit.
REM #*#LIssAvouar
REM PLOTS LISSATQUS PRTTERHN
$
2
З REM Я IS RELATIVE FREQUE HC?
B IS REL. FREQ. Х,С 15 Y PHRI
BIG MENT “INPUT A (INTEGER 1 T
2@ INPUT A
oe FRAN “INPUT E {INTEGER 1 T
в
SO PRINT "INPUT C (ANY HUMBER
Ба INPUT С
50 FOR ғ-о TO 20a
90 LET Y=S3@+S04S5SIN (ConaPIaPsi
те LET Xz20420*5IN (BxPIsT»igc
110 PLOT v,x
120 NEXT F
"v заза, E ап = 1а ur"
= = gd 2" я " N E ie а т
> x to `. a в .. "ag "er
7. Line
This program gives the computer the capacity to draw a line between specified plot co-
ordinates. The Spectrum possesses a LINE instruction that does this automatically, but
Spectrum users may be interested in the method, which is the way the LINE instruction
automatically calculates the points to plot. The program will run on the Spectrum if
line 85 is deleted. As it stands, the program prompts for two sets of X, Y points, giving
an error message if the points are out of range. Lines 110 and 120 calculate the X and Y
axis differences between the specified points. Line 130 defines the variable A as the
greater of these. DX and DY are the increments added to the values of X(1) and Y(1)
509
for plotting. In the loop (F = 1 to ABS A, since A may be negative) DX and DY are
decremented or incremented (as X and Y are positive or negative) by the distance to be
covered between points, divided by the number of steps needed. The program will
accept further inputs as required, but does not provide input prompts (lines 210 to
280).
5 REM "LINE" "
iO REM DRAWS LINE BETWEE POIR
T.,(XC1),VYCLIIAND POINT ах+ш v 1E
3 1
20 DIM X12)
25 DIM Y (2)
50 FOR Ғ-1 TO 2 ©. --
40 PRINT “COORDINATES POINT “i
со PRINT "A UGPLUSE Т"
50 INPUT Р)
70 PRINT
^
(
"Y VALUE Т”
(F)
>
К 1355 THER
PROGRAM AGRIN ``
DY =@
16568 FOR F=1 ТО 65 n
179 PLOT ОРТАҒЫ DY £w ££
180 LET DX=DX+X/ABS F
190 LET DY= DT te CABS e
2BO NEXT F
219 REM FOR OTHER LINES
220 REH M ркан жїл
230 INPUT X(1)
ТОЧНИОТ HS ИШИН
8. Reverse
The computer jumbles up a sequence of 9 numbers, and prints these (subroutine line
500) after giving the instructions, by calling subroutine 1000. After each input by the
player the subroutine at line 300 is called to print the altered sequence and check if the
ordering is complete. If the sequence is correct, control is passed to line 2000 for the end
routine, which gives the option of playing again.
18 REM “REVERSE”
20 PRINT TAB 10; "#REVERSEs"
зе GOSUB 1000
CLS
45 DIN
R (9)
50 PRINT TAB 10;"'xREUERSEx'
во PRINT AT 5,5;
510
ге GOSUB See
өс LET GOES=Ə
ae PRINT AT 15,0; “INPUT NUMBER
TO REVERSE 77"
100 INPUT R
110 IF R:1 OR R»9 THEN GOTO 100
120 GOSUB 380
136 REM xxLOOP NEXT GO#*
148 GOTO 100
150 REM =#=# += # +++ + +++ + * + + +++ +++ Ж
160 REH
5020 REM rx*xREUERSE AND СНМЕСКЖжЖ
310 REM +#SEQUENCE xx
315 REM
320 FOR F=1 TO INT (R72)
USO LITT T=A tF)
S4@ LET ЯР) =A (R-F+1)
3550 LET AC(R-F+1) =T
360 NEXT F
370 LET CORRECT =
3882 PRINT AT 5,5;
390 FOR Fz1 "T 9
400 PRINT atF2); T
410 IF AIFI =F THEN’ LET CORRECT
=CORRECT +1
429 NEXT F
4232 LET GOESzGOES—-«41
440 IF CORRECT=9 THEN GOTO 2009
450 RETURN
460 REM #++ ++ +++ ++ +++ +++ ++ ++ +++
500 REM ##S5ET SEQUENCE #*¥
510 LET ACL) =INT (RND «933 +1
TO 9
S30 LET R (F) 2INT (RND#9) 41
540 FOR N=F-1 TO 1 STEP -1
550 IF ACF) =яМ) THEN СОТО S30
550 FOR F=1 TO 9
S90 PRINT R(tF),;" ”;
600 NEXT F
6180 RETURN
620 REM =з» ++» ++» ++ +++
6380 REM
19006 Бен *£*INSTRUCT IONS жж
1820 PRINT COMPUTER GENERATES
JUMBLED", "SEQUENCE OF DIGITS 1
TO 9.
1030 PRINT “YOU MUST INPUT A NUM
BER 1 ТО 9,
1040 PRINT “AND THIS NUMBER OF D
IGITS,","STRHRTING FROM THE LEFTM
OST a's "UILL REVERSE.YOU MUST GET
2858 PRINT DIGITS IN ORDER LEFT
TO RIGHT.'
БЕРЕ PRINT ,, "PRESS R KEY TO STR
1 @ PRINT s "THERE WILL BE A DE
TU WHILE”, “SEQUENCE IS CREATED.
10628 PAUSE 4ee00
123290 RETURN
4100 REM #= FF EXF FSH + + +++ +++ +1 ++
REM
5000 REM sxEND ROUTINE
2005 REM
AT 20,0; "##SUCCESS IN
2619 WES; GOES#s", "ANOTHER GO? CY
м
2030 IF Hao ye THEN сото 2050
SYE
9939 STOP
9. Tools
The program shows the principle of a programmer’s toolkit program containing useful
program modules. You should add to this basic version any further subroutines or
modules you want to have available. The inclusion of the BLOCKDEL program makes
511
editing out any modules not required for a specific program very easy. You may wish to
add, for example, a round/justify subroutine for numbers, or a sorting subroutine
Note the mnemonic for the error subroutine line number. When you add modules
however, use variable names that you are unlikely to use in the program you are
developing. Load the program before starting a program on the ZX81.
Spectrum: For the Block delete module see BLOCKDEL. For Renumber module and
Memory left see Section U of the text. Remember you can use MERGE to enter this
program at any point (hence the high line numbers).
m gj & Umm
00
S480
S33S6+256*#PEEK 163387-PEEK
SexPEERKR 16413;
S540
9550
REM
REM
REM
"TOOLS"
£slLLUSTRHTES TOOLPRIT a
езі ОНД) BEFORE START ++
Fe INPUTTING PROGHHRIX:X
*xGO0SUB ERROR FOR =н
+ *KHESSAGE
##GOTOQ ашаа FOR aL Ock ++
#*#DELETE
xxGOTO 9700 ғоя BENUM
*xGüOTO S458 FOR MEMORY
*LEFT
ADO YOUR QUNM ROUTIN£ZI
£ £ £ £ £ + £ $ £ + AHA $ $ HAAHA RABE
ЕКРОВК =94.00
ERROR MESSAGE 508+ 4
* * Xx X X 3 3 Д < 3 HHH
PRINT TAB 7, “#844 INPUT ERROR
T); RERSRERHRHH4HHHHH ES”
PAUSE 120
REM #xHEMORY LEFT із
are SHH HHeHAH HAHAH ++ +++ HSH SSS
PRINT “MEMORY LEFT ="; PEE
264325 —;3
"1
=
—
=
ae
APPROX,”
STOP
REM x*BLOCK DELETE::
REM 3 * s š 3*3 š € € s£ š š
PRINT “FIRST LINE TO DELETE
INPUT ST
PRINT "LAST LINE ТО БЕ DE: =
INPUT END
LET RANM=16589
9560 LET LNUM=2564PEERK RAMNSPEER
(НАМ +1)
3570
+2
3530
ЕЕК
9
9560
SLETE BLOCK
ауа
3500 IF 25б%РЕЕК БКИМФРЕЕК
1 =9000 THEN GOTO 3832
3512
3520
93530
SUB , сота",
354ea@
IF LNUMZST THEN LET LRBH=RA
LET LLEN=PEEK S iRHlh-2!4286037
(RAM +3)
um “Бына END THEN GOTO ЭББ
RAM=RAN4+¢4+LCEN
GOTO 3568
LET LLENsSRAM-*LLEN 2-154
PORE LRAM+I1, INT YILLEN.2986561
POKE LRRHM,LLEN-2SOGsPEER ILR
PRINT “INPUT FIRST tei TO >
=
STOP
REM #x#RENUMBER #+#
REM ££ £ * * š * $ GR +++
LET mRhüM-zilesaa
LET LINE =2@
LEIL ӘТЕРсіе
POKE RAM, INT (LINE.2wU6
POKE RAM*«1,i!LINE-z296643P££NH
LET RAM=RAM+1
IF PEEK RAMI >o4148 THEN GOTO
=RAM+1
=
3770
LET RAN
URBI +S
LET LINE-LINE-«STEP
GOTO 9750
PRINT | SRBEUBEREBA NOW DO Go
“LINES
STOP
512
10. Blockdel
Program enables blocks of program lines to be deleted by a single line entry after the
line numbers of the first and last lines of the block (ST and END) to be deleted have
been entered (the program can also delete itself!). This is done by taking (line 9550) the
start address of the program storage area (RAM) then finding (line 9560) the line
number of the first line (LNUM). If this is the line number of the start line, the address
of the first byte of the line length storage bytes (= RAM + 2) is stored as LRAM (line
9570). The line length bytes are then PEEKed (line 9580) to find the line length in bytes
(LLEN), before the line number is checked in line 9590 to see if it is the last line to be
deleted. If it is, control is passed to line 9620. If it is not, RAM is incremented by the
line length and four bytes for the program length and line number bytes, to get the
address of the start of the next line stored in the memory, and the process is repeated.
When the end line number has been located and control passes to 9620, the line length
variable LLEN is made equal to the number of bytes between the first and last lines for
deletion (this is why LLEN was found before checking if the current line was the last of
the block) by setting RAM to be RAM + LLEN, i.e. the address of the end byte of the
last line to be deleted. This value, less the address of the line length byte of the first line
(stored as LRAM), plus 2 for the program line number bytes of the last line gives the
number of bytes to be inserted by the POKEs of lines 9630 and 9640 as the new line
length of the first line requiring deletion. The computer now thinks that the lines for
deletion are all one huge line, and keying in this line number and pressing NEWLINE
(ENTER) will delete the whole block. The program should be loaded for use on a ZX81
from tape before you start working on a program. Spectrum users can use MERGE.
Spectrum: Line 9550 (giving the start of the program area) must be changed to read:
9550 LET RAM = PEEK 23635 + 256* PEEK 23636
ле REM “BLOCK CEL
3508 214 **8LOCK CELETES4
3505 R * * +++ т
3510 PRINT "FIRST LINE TO DELETE
S528 INPUT ST | к
S530 PRINT “LAST LINE ТО Sr Prise
S54@ INPUT END
assa LET ВАМ=16509
S580 LET LNUM-2SBsPEEK Янә
422” IF LNLIH=ST THEN LET ЬЯ =
ssaa LET LLEN=PEER (8816523 PRSA 3=-
ЕЕК (RAM+33
S590 IF LNUM=END THEN GOTO Q822
зеса LET RAN=RAN+44+LLEN
2610 GOTO 9560
3620 LET LLEN=RANF+LLEN22-L RM
зеза POKE LRAMS1, INT ЕЧ soa
29649 POKE LRAN,LLEN- 256 4PEEA tLe
+1)
$630 PRINT “INPUT FIRST MG TO Z
ELETE BLOCK"
S668 STOP
10 REM "“BLOCKDEL"
9500 REM ##ELOCK DELETE жж
2505 REM EEE EH HE жы Ж
2510 PRINT "FIRST LINE TO DELETE
$520 INPUT ST
9530 PRINT “LAST LINE ТО BE DELE
TED?"
2540 INPUT END
9550 LET RAM=146509
513
2560 LET LNUM=275e% PEEK RAM+ FEE
қ CRAM+1 >
9570 IF UNUM=ST THEN LET LRAM=RA
M+2
7550 LET LLEN= PEEK (RAM+2)4+254.%
PEEK CERAM)
2590 IF LNUM=END THEN GOTO 2620
7400 LET RAM=FRAM+44+LLEN
9510 GOTO 60
7630 LET LLEN=RAM+LLEN+2-L RAM
7640 РОКЕ LFñM+1: INT (LLEN/226)
9650 РОКЕ LRAM:+LLEN-256% PEEK xL
RAM+ 1)
9660 PRINT “INPUT FIRST»N/L Tü D
ELETE BLOCK"
76470 STOF
11. Coder
The computer chooses a four digit code sequence comprised of the digits 1 to 6. You
input your guess for this code sequence. The computer prints your guess, checks for the
number of digits in the correct place which correspond to the code, storing this as AST
(for asterisk), and then checks through the remaining digits for numbers which occur in
the code sequence, but are not in the correct place (DOLLAR). These values are then
printed. This information helps you to refine your next guess. 15 goes are allowed, and
if you haven’t got the code in 15 tries, it is printed out for you. The program is
structured with a sequence of calls to subroutines. Note that the code can include
repeated digits, and analyse the checking procedures to see how this is dealt with.
REM “CODER "
GOSUB 1006
REM ТАНА а-а AND xx
(Жы
LET Neo" 22 345
- 1i! = в“
FOR F=1
LET Z n DENS сават «БҰМҒГАн6,ҙ €i:
fos
IF MARK=1 THEN GOTO 1:38
LET GUESS=GUESS+21
PRINT RT GUESS +2. 1i Gg: TRE
GOSUB сос
GOSUEB 608
PRINT AST; TAB : DOLLAR
REM ж%ҰЗЕЕ IF 15 TRIES жи
+ xOR CODE CRRCHEDxrxE*
F pe yku e e
HUGO бб SEeaqQgqao был
Sod J OAM mu vu e» Ct
Тае
219 IF AST=4 OR GUESS=1Z> THEN
GOTO 2868
220 REM ab icr adi TO NEXT GUESS
езе GOTO 11
240 REM ^o наказание най
258 REH
222 REN
E *xCHECH INPUTrEE
$95 BEN á
: I F-L TO LEN &G
аша Gg (F) аз THEN 24 om TODE
< N
аза ЫШТ LET MARAH = 1
440 IF LEN 5Ф<>4 THEN LET ter.
514
450 IF NOT MARK THEN RETORN
4603 Gn 2 NB AT GUESS-«3,.0;
7 ";G$;"7? TRY AGRIN.*
a7 PAUSE
480 PRINT AT GUESS-T3,0;"
42a RETURN
435 REM хжхжжғғжхжкжғккккккк
ЕМ
5020 REM *=*=F IND NUMBER x +
520 FOR F=1 TO 4
530 IF AS(F)I<>GeiFs THEN ТГ
570
қой REM SSH x yx x z£ x x x x k x EEE
520 REM xxFIND fj HRHUPIEEEE y x
еге LET DOLLRARRzO
өзе FOR F-1 TO 4
FOR N=1 TO 4
550 z g eth) rop On THEN GOÜTOG
LET DOLLAR= DOLLAR +2
LET AS(F) ="X
44 4 CL Qn
e guo
OGOOGO
r
m
-f
G)
2
11
ext
RETURN
22 REM хжххккккжккккккк
730 REH
1oo00 EE *3x INSTRUCT IONS + +
EM
іга PRINT TAB 12; VN SEEKER" | TRE
12; “+СООЕК +; TAB 123;' ‘SEER ER К“
1@38 PRINT .. “COMPUTER CHOOSES =
SEQUENCE ОҒ“,%4 NUNBERS.THIS I=
MADE UP OF", "аму OF THE DIGITS
i TO а”. “INCLUSIVE. DIGITS MEN EE
R LE
1 "YOU INET SEGUENCE
5 TO TRY i Nb “MATCH THE CODE."
1050 PRINT ,..^COMPUTER HILL PRIN
T NUMBER OF B.SIGNIFYING CORRECT
DIGIT IN". "RIGHT POSITION . CPU, ғ
UMBER OF = ,HERNING € DIGIT Із G
HESS WHICH
19509 PRINT “OCCURS IN THE гомгазт
ERS CODE, , BUT IS NOT IN THE БТ
GHT PLACE.‘
41070 PRINT ,.," PRESS A KEY TS Ek, =;
1280 IF ІМКЕУФ-““ THEN GOTG LGE
1090 RETURN
1192 REM EEEIEE 3 38 ККЕ
5228 REM END ROUT
: шо INE x x
5929 НЕМ ast 4 THE?
282 = ч GOTO 205
2023090 PRINT "15 TRIES AND NO Sr:
ESS.CODE"."uns "209
5058 ERENT Mec
сый: - " e E > è £z.
na RTRS CESS ІМ í GUESS,
cuo T “ANOTHER Ge Ti i
т OR NOS GAME IMPLT
2UTO INPUT MS
zasa IF Мф-“У" THEN GOTG Zu
2290 CLS
заво ERUNT "DC BYE.”
2350 RE
292930 REM *xx«xxxrxENDEEXExEeEk
3999 STOP
"BB GUESS
E
1
3
3
GG ts
515
S432 1:2
2342 32 X
5122 т.
siloa е 1
13923 | 9 3
бізг i =
1362 1 2
4532 s uk
S332 12
4352 з 2
3342 г е
3512 4 0
SUCCESS IN 15 TRIES?
RNOTHER GAME? { INPUT Y OR H
12. Plot
A simple program to plot a graph of data points, with X and Y values input on the
screen. Prompts for X and Y axis minimum and maximum values are made, and string
inputs for the axis titles. These are then printed, and the data input is prompted. X and
Y values for each data point are entered, which is then plotted, and more data is
requested.
Spectrum: Change line 310 to read PLOT 124244 * (X- AYy(B- A),
12 + 156 * (Y — C)/(D - С)
2 REM PLOT se
дё PRINT TAB 6: BSR SE rei сут ET
2à8 PRINT
3@ PRINT "SET AXIS RANGES"
40 PRINT “INPUT X AXIS MIN. vat
SQ INPUT A
SA PRINT A
70 PRINT “INPUT X AXIS MECN Ue
se INPUT Б
за PRINT Б
© PRINT “INPUT Y AXIS MIM. UAL
а” INPUT с
€ PRINT “INPUT Y AXIS MAX. VAL
14@ INPUT D
D
i58 PRINT “INPUT X AXIS TITLE "
IT a P
іза PRINT X$
152 PRINT “INPUT Y AXIS TITLE `
“ора INPUT Y$
210 PRINT Y$
220 5
230 PRINT AT 21,6;:X$&
249 FOR I-1 TO LEN Y$
250 PRINT AT I«5,.0;Y&1I1j
592 PRINT AT ә.
228 ERENT S ©; INPUT N
т NT AT @,0;" v
266 таат 9 O; “INPUT `
UE. p I rius X-A Z CE; — € y , Seay
зда GOTO 279
13. and 14. Bidec
Program converts binary numbers to their decimal equivalents. Two programs are
given, differing in the conversion procedure applied to the binary number, which is
input as a string. The algorithm of BIDEC*2 is more transparent than that of BIDEC.
Spectrum users have the facility to input binary numbers directly (using BIN), but this
516
cannot handle numbers input in the course of a program, or generated by a program,
in which case a routine of this type is required.
BIDEC*2
Spectrum: À not ** in line 50.
š REM #BIDECs
REM CONVERTS BINARY NUMBERS
INTO ee tee
18 "ENTER BINARY FORM"
110 INBUT A$
158 PRINT Өй IN BINARY I2"
348 LET R=LEN AS
150 (ЕТ NSURL & was
160 FOR Fz2 ТО
17@ LET М S ема. F$ IF)
ico NEXT
RINT.
әде PRINT N;" IN DECIMAL”
o REN "BIDECx2"
180 PRINT “INPUT BINARY NUMBER"
SØ FOR F=LEN БФ TQ 1 STEP -1
БӘ LET es иши BS i Fl £ xP
Та LET P=P+
зе NEXT F
oa PRINT B$; “=DECIMNAL “iN
15. Hexdec
Program converts hexadecimal numbers up to FFFF (65534 decimal) into decimal. As
with DECHEX, the straightforward conversion of a character code to a decimal value
which is possible on the ZX81 is more complex on the Spectrum. Line 130 in the ZX81
version uses the value of the loop variable K directly to get the decimal value from the
character code. On the Spectrum a counter loop is set up to hold and increment the
value of K, and a new variable Z is used to hold the number by which K is to be
reduced to give the correct decimal value from the hexadecimal character.
Spectrum: Line 50 needs À , not **
Insert 55 PRINT ‘‘ LETTERS MUST BE CAPITALS."
Insert 115 LET K = 48: LET Z = 48
Change 120 to read 120 FOR Y =0 TO 15
Change 130 to read 130 IF A(F) = К THEN LET N = ((K- Z)*X)+N
Insert 135 LET K=K+1
Insert 136 IF K = 58 THEN LET K = 65:1ЕТ Z = 55
Change 140 to read 140 NEXT Y
КЕМ x*HEXLDECrx
4)
INT
50 PRINT "ENTER HEXADECIMAL NG
"rr
omm
DA-
хх I
11 И
wu
+°:
++ OO
о
LEN Ar
ODE H$IF;
„ЕН ris F}
K THEN LET N=i t -2E
“Wr TP I T
жи
X Gia p eu A
` (S € 9 баб) (3
Ж
m
4
II Qo
-.
ээк Бараа л
42 NEXT
=
(Ji
б
1
D
H
z
"n
WX Th
I9 ";N;" IM DECIMAL.
517
@ PRINT
© PRINT "RHGRHIN'?7íN OR Y`
© IF INKEYS$="Y" THEN GJOTG SS
а STOP
16. Dechex
Program converts decimal (base 10) numbers up to 65534 to their four-figure
hexadecimal/(base 16) equivalents. Hexadecimal numbers use the digits 0 to 9 plus the
letters A to F. This requires a means of deciding which character is to be printed, after
the decimal number has been broken down. On the ZX81 this is simple, since the
(capital) letters A to F follow directly after the digits in the character code sequence.
This is not the case on the Spectrum, and the gap in the sequence must be bypassed.
CHRS can then be used to change the decimal values (0 to 15), into which lines 120 to
170 break down the input number, to the appropriate character.
Spectrum: Change 190 to read 190 LET X = 48
Insert 205 IF X = 58 THEN LET X = 65
TO 19
IF FiiF)=y THEN LET AR&iF;-5H
LET жн x+1
Jj
PRINT " IS “AS; IN HEX"
PRINT AT ENR т NEWLINE
UN AGAIN"
Ces p. cana
mor iU TO EO EG e [Ú [U R9 ei i RP ро RS F2
1 REM DECHEX
аа DIM Aig)
сә DIM АФ (4) С
за PRINT “DECIMAL BASE TO HENA
DECIMAL BASENUMBER CONVERS TION™
4а PRINT
БӘ PRINT "NUMBERS «85555 Gni“
ge PAUSE 35
76 CLS
S0 PRINT “INPUT DECINGL UD 0E"
ай INPUT М
аа PRINT
12 PRINT N;
ЕФ LET ACIVI=SINT (Ne 4 O58’
За LET B=N-A(1) £4636
4@ LET ACBi=INT (8-258;
ей LET C=E-F (2) +258
ео LET Alsi SINT (O-26s
79^ LET Aid) s=C-A(Ss £16
зе FOR ғ-і TG 4
acd LET X=26
eo FOR Yzà
із
x
e
e
e
e
o
m
a
a
%0-.|
17. Gridhunt
Тһе computer hides itself on ап 8 Бу 8 grid, which is displayed оп the screen. You input
your guesses of the co-ordinates, the guessed square is marked, and if not correct the
computer gives a prompt for its direction from this square, using compass directions.
4 REM ¥*¥GRIDHUNT ж
із PRINT —""iaekütal*sgs
зә FOR Xz2 TO 18 STEP 2
24. IF srana TREN COTO 46
ху»
40 PRINT AT 3,X; -";HÍi 14,х; "+
45 PRINT AT 441,22: "+"; RT xX+1l ,1
G3 а.
БО NEXT X
60 LET E=INT (t(RND#53) +1
78 LET М-ІМТ (RND zx: + 1
Зб LET G=lE-1} +N
ga LET H=@
518
108 PRINT AT 3.28; "YOuR GUESS: —
"AT 3,20; a ae ia
Li@ INPUT
128 PRINT Ят 5,26," ";яЯ; АТ 2,29
з “DOWN?”
130 INPUT D
131 FOR Xz1 TO S
152 PRINT RT 2-«Dzx2,1-24a0*2; Ж.
133 PRINT AT 2+0%+2,1+я+2; "Y
134. NEXT X
135 PRINT AT 2t042,71+AR2S; “ж
14@ PRINT AT 7,24;" ";г;ат 9,20
145 LET М=М+1
150 LET С= 9-1) #642
160 IF C-G THEN сото зай
2
=
190 IF N>D THEN PRINT "S";
2OD IF N:D THEN PRINT "N";
216 IF EYR THEN PRINT "E";
220 IF Е‹А THEN PRINT "UW";
әзе PRINT " “;TRS S2,"OF YOU"
222 PAUSE 2080
250 FOR X=3 TO із
Р
300 PRINT “GOT HME";ThB S2,;"IN ~
19 PRINT AT 20,89; “PRESS A KEY
TO PLAY“
see IF INKEYS$="" THEN GOTO S2@
330 PRINT AT 20,8;
349 CLS
358 GOTO 1G
18. Rescode
Program calculates resistor values from inputs of the colour bands on the resistor.
Three bands are input, end band first, using the abbreviations given. The first two
bands define the basic value and the third the multiplier.
32 BRYBESEOPE
"ENTER COLOU У
NDEAND FIRST" ee MESS
3e INT
айд PRINT “USE CODES AS БЕ ОШ:
во PRINT ТАВ 6; “RED RE'; Тағ
6; "BLACK 6L"; TAB 5:"BROUN BR"
; TAB 6; “ORANGE OR’; TAS 65; "YELLOW
"YE"; ‚таз 5; “GREEN GR’; TAB 6; “BL
МЕ BL"; TAB 6; "UIOLET VI’; TAB &
; GREY Gv" TAS o; "WHITE UH",T
nb Б; "GOLD GO"; TPE ё; “SILVER 5
X^
вә FOR A=1 TO 3
Ж. PRINT "COLOUR ";A; "7 n2
ве INPUT C$
өй PRINT C$
100 IF C$-2"BK" THEN LET U=@
110 IF CS$-"BR" THEN LET Uzi
12@ IF Сф= “НЕ” THEN LET Uz2
130 IF C$-"0R" THEN LET Uz3
140 IF C#="VYE" THEN LET V=d
150 IF C#="GR" THEN LET Ч=5
160 IF С%-"Еі. THEN LET V=s
170 IF Сж-"МИІ" THEN LET М-?
48@ IF cCH="GY" THEN LET УӘ
190 IF C$-"UH' THEN LET Uz9
оаа IF C#="GO" THEN LET U-i0
210 IF Cs” SI" THEN LET іші
эра IF n-i THEN LET F=
2:30 IF R=2 THEN LET FoF He LG+u
24G NEXT A
250 METNT “RESISTANCE VALUE IS
bea IF U9 THEN БОТО Зва
519
S10 PRINT " OHNS"
S6Q PRINT Fev;
370 PRINT " OGHHS
19. Marker
Program produces a marksheet for the pupils in a class after exam results are entered in
five subjects, set in this program as English, Maths, French, Computing and Biology.
The average mark for each pupil is calculated, and a grade breakdown of the results is
printed, giving the total number of pupils in each grade. The grades are defined as:
45% or less FAIL
45 to 7596 PASS
More than 75% DISTINCTION
As initialised, the program allows up to ten pupils in each class. A pupil name is
entered with the results in each of the subjects, and the average calculated. When all
entries have been made, END is entered and the subjects, results and grades for each
pupil are printed. The grade breakdown is then given of the number of pupils in each
grade for each subject.
1 REM “MARKER”
5 LET Ti-e
S LET Te=8
7 LET Ta=e
, 8 LET Z$-z"END
да DIM AB$ir18,20)
20 DIM RIID)
25 DIM Di5!
вв DIM PS:
27 DIM F (Š
За БІН S$1í5,1i0)
да DIM H(3i@ S)
52 PRINT “MARK SHEET"
GE PRINT “аға,
т^ PRINT ""
зә PRINT “С
100 LET Ісі
іле LET Com
РО КЕТ SEII: "ENGL FSH”
АЗА LET ss te) =" МАТН"
TES КЕТ 59:95 =“FRENCH"
150 LET S$ it? -“СӘМРОТІМС"
160 LEFT S$tS) ="BIOLOGY"
22020 PRINT “EN ЕН NAME CENTER Ef
p TO FINISH): ^"
21ı1@ INPUT RSet
ере PRINT REL
ONHH
а” ғ»
езе IF mn$i1?
езе SOSUE ive
250 LET Ісізі
ese LET C=C+1
255 CLS
268 сота гае
Sag REM CALC RVERAGES
элт соғу
THEN бОТО See
2) +R t L)
ос
өзе PRINT "МАМЕ :"; ABET?
6249 PRINT "SUBJECT"; TAB iS; “HAN
K"; TAR 2@; “GRAPE”
сест eater ortega
638 FOR U=1 TO 5
6535 IF М(І,о3575 THEN GOSUB 2ee
626 IF MET, 42 245 AND MOI, N 275
THEN GOSUR 222080
" ad YF Mi, <=45 THEN GOSUR 24
520
GEA PRINT ASE; TAS i15; MCI, iT
AB 22; =s
6S@ NEXT <
665 PRINT ""
666 PRINT “AVERAGE= “JANS
667 PAUSE sae
668 COPY
өзе CLS
67e NENT X
700 PRINT “GRADE BREAKDOWN BY =
UBJECT “
ТЇЙ PRINT “--------------------
?29 PRINT “SUBUECT'; TAB 25; "PD IS
T.“ FRB PZ; PRSS“, TRE 27; “FRILL”
725 PRINT ~”
тз БОК (u=: FO
740 PRINT 23 (49; TTAB ір TRB
5e LET Ті-тізб cay
Zëw LET Fe=TesP U.i)
тта LET TAs Farr 522
S20 PRINT “TOTAL”; TAS 15; 74; TAS
22;T2; TAS 27,T3
ase STOP
BBR ROM INPUT гата
ӘӘ FOR =i TO 3
ДЕР. қ аын "USUBRBJECT “;5%%0»;” MR
1858 INPUT Hr.)
Өте PRINT Hül,.)
Loan NEXT М
11 RETURN
зала REM DISTINCTION
SQUIB LEF G$= DISTINCTION"
2020A LET о =O tt + 1
203a RETURN
2200 REH PASS.
гїї LEF G$ =“ PRES”
2220 LET FP XG =P (<!) +1
2230 RETURN
mao REM FRIL
242@ LET G£-"FRHIL"
2420 LET Fifi =F (<i) жі
2438 RETURN
20. Indate
Program is a date entry routine, with the input subroutine starting at line 10, and,
nested within this, an error notice subroutine at line 250. On running the program,
control passes to line 300, which has a short example of the manner of use of the
subroutines. Subroutines are usually grouped at the end of a program, but they can
equally well be put at the beginning, as shown here. With long programs, using the
subroutines repeatedly, this can speed execution, since the computer counts from the
start of a program to find the line number corresponding to a GOSUB or GOTO
destination.
1 REM "INDATE”
2 REM xDHTE INPUT ROUTINES
3 REN DATE ENTRY “CHECK SUBRO
UTINES.ENTRY GOSUB iG.ERROR HESS
ARGE GOSUB 250
о GOTO See
S REM +w == хз кк.
Э REM ##DATE ENTRY SLE x x
1e PRINT "ENTER DATE“
26 PRINT "OmnmV7"
зә INPUT D
49 IF D>=1 AND D<=5>1 THEN СОТО
со GOSUB 250
TO 20
ге SEN ` ¿pra AL то 3203
Әй IF M>=1 AND М<-іг THEN сото
іре GQOSUB 250
110 сото 74
i209 PRINT “YEAR?T‘AS LAST 2 DIGI
521
130 INPUT Y
140 IF vY»10 AND Y<9S THEN GOTO
ісе GOSUB 2560
169 GOTO 12€
170 REM CHECK DRY М5 MONTHS
180 REM xLERHP ‘EARS |
1a! IF ІМТ (t¥4i3@8) 24) <> (Y +1ƏG
о) /4 AND M=2 AND с=з THEN GOTO
сб REM SHORT MONTHS
210 IF NOT ({M=2 AND D:28) OR t
OR M=6 GR M-9 OR hH-11) AND
Б-311: THEN GOTO 249
220 GOSUB 250
238 GOTO 19
240 RETURN
245 REM #=# =s X 3 + Xx x zy x x x Z= 3 3 % + X ЖЖ
249 REM szszsERROR NOTICE SUBS
250 PRINT “*###INPUT ERRORSss","
PLERSE FOLLOW INSTRUCTIONS", "ВЕ –
INPUT REQUESTED DATA.”
260 PAUSE 180
270 CLS
250 RETURN
зой REM *¥##PROGRAM HERE ТО USE
INPUT ROUTINESs*x
318 REM #EXAMPLEs E
320 PRINT “YOUR BIRTHDAY"
3360 GOSUE 10
2
lI
b.
PRINT “BIRTHDATE: "`; BD; "+"; Б
21. Headliner
Program prints banner headlines on the printer, using the character arrays stored in
ROM. As listed, the program allows the inverse characters of the ZX81 to be used,
accessing the normal character (line 13@) to get the pattern of bits, but reversing this
(1.е. swapping black for white) for printing (line 560). This procedure is not possible on
the Spectrum, since the inverse forms are not included in the character set. The basis of
the program is the reading of the character arrays (as with the BIGPRINT program in
Unit U3 of the main text), but with the additional complication of reading the first bit
of each byte, then the second bit of each byte, and so on, in order to print a character
with a sequence of printer lines.
Spectrum: Delete lines 40, 120. 130, 550, 560
Change line 160 to read: 160 LET L = PEEK (15360 +
C+8 * CODE L$)
L REM *#HEADLINER:
10 PRINT TRE 5; "im
ез PRINT ,,; PROGRAM TO PRODUC
E LARGE PRINT", "AS HERCLINES ALG
NG PRINTER PAPER”
GO PRINT ,,;" "INPUT ANY LEN&TH
STRING."
40 PRINT ,,;" YO: MAY USE ALL L
ETTERS , NUMBERS", “AND GRAPHICS.”
Se REM CIM RRRRY ТО STORE LETT
во DIM Яќ54.)
70 INPUT U$
ва FAST
Эе FOR Е-і TO LEN U$
100 REM TRKE LETTER
118 LET Іі %-ііФІҒ)
124 REH IF CHR INVERSE THEN
SURF FOR NORMAL FORM
азе IF CODE L$»63 THEN LET L§$=C
HR* (CODE ЦР) -126)
140 REN SET кәм COGOZ3
156 FOR с-а YO 7
¿150 LET L-PEEK (7680«C45sCODE L
j
e
522
170 REM GET BINARY INTO BERRY
180 FOR B-1 TO Gg
190 IF L-exsINT (iL^2)-1 THEN GOT
200 LET AIiSsC+B)} =o
210 GOTO 238
22 LET RíOGxc-5)-1
230 LET L-IN!T (1/23
240 NEXT B
254 NEXT С
рес GOSUB саз
278 NEXT F
сазда REM PRINT SUSROUT INE
510 REM REVERSE LOOPS
52 FOR X=8 TO 1 STEP -1
S3@ LET niz fe
540 FOR @ STEP -1
550 REM REVERSE IF CHR INVERTED
ВЕРОНЕ
See IF CODE U$ (F?) 5655 THEN LET A
{т €*5O-X) =NOT ACY x€ +X:
2; REM PUT ONE ROR GF CHR INTO
Ag
оза LF R (Y*S+xXx)=1 THEN LET A$=A
S90 IF RO xG4X)-0 THEN LET AS=R
AS
S20 LPRINT RS
Do0 NEXT X
64@ RETURN
22. Input
Program checks a number input as a string. This is a useful way to input numbers, as
an error will not cause a program halt, as will happen, for instance, if a numeric input
contains more than one decimal point. The program is listed as an input check for
decimal currency, but is easily modified to suit any numeric input of a known form.
The string input is checked by the subroutine at line 200, each character in turn
being checked by means of its code to ensure it is either a digit or a decimal point. To
check for multiple d.p.’s the counter S is incremented each time one is encountered. M
is set equal to the number of digits before the d.p. A check is then made for S being
greater than 1 (non-numeric character or more than one decimal place), @ (no d.p.),
and for more than two digits after the d.p. Any error sends control to the error
subroutine at line 400. This requests a re-input the number. The error check
subroutine is then called recursively to check this input. A correct input will pass
control back to the main program, where the user is given the opportunity to check that
the input value is correct.
1 REM "INPUT'"
STRING INPUT CHELNED RS
REM *#MARKERS x
16 LET 5-0
E ken ss
М EMPTY LINE:
20 LET E&-" £
**
30 PRINT “ENTER BHOUNT . ENTER
OUNDS.","FULLSTOP,P E E
аа INPUT NG SPR Tec
ET
OFFER VALUE CRECH E
entry Бай SMS SQ тысы Ut ID.
Vt < ^ x` :yT x Г. ГЕ
ТЕМ,Е TO RE-EN ж Т тнт
78 INPUT аф
SQ IF Ag="C" THEN GOTO 178
30 IF A$="E" THEN GOTO асс
,480 PRINT AT 20,9; “FOLLOM INSTR
116 GoTo за
120 PRINT AT 29.9;EF&: ES
130 PRINT AT 20.0. “ENTER ЗІ ЕЕЕ
T UBLUE."
140 INPUT N$
150 PRINT AT зә.о;ғе:ғе
923
160 GOSUB 200
170 Crs
150 PRINT “END OF PROGRAM
130 GOTO 999
133 REM *ERROR CHECK +
200 LET L=LEN N
210 FOR F=1 TG L
219 REM *CHECK NON-NOÜMEDRIL CRET
220 IF CODE a. oa” OGR СТИХЕ ME
F)»37 THEN LET S22
2293 REM xCHECH ҒІҢА ЕТЕ
ә: IF МФХЕЗ =". THEN LET 5-е еі
240 am £L. p^ z"," THEN LET rtzF
B= ЗЕ Ж OR 5,2 Gh £=& THE
ы GOSUE 486
333 REM sERROR FOUND:
ғас PEINT AT 23, Oi“ £IMFLIIT INURL
IDsRE-EMTER URLUÉ"
418 INPUT H$
LET ©
412 E = =
412 LET Мб
420 GOSUB 200
430 RETURN
299 REM END
23. Asteroids
The program puts you at the helm of a Mars shuttle disguised as an asterisk. Avoiding
the Nova Heat you have to weave through the strangely square low albedo asteroids
that look surprisingly like inverse squares. Your controls are fairly minimal - not much
money on the Mars run smuggling algae these days, so you have a button marked 1 to
go left and one marked 0 to go right.
The program cannot be simply modified for the Spectrum so this listing applies to the
ZX81 only.
= REM "ASTERDIDS"
10 PRINT "x«ASTERDIDZ3«"
20 PRINT
Р 30 FRINT “AVOID BLACK ASTEROID
40 PRINT “YOU STEER YOUR SHIF
сж)"
SO FRINT "BY PRESSING 1 TO GO
LEFT"
во РЕІМТ “AND 0 TO GO RIGHT"
70 PAUSE 400
во CLS
90 РПКЕ 1641538
100 LET 50
110 LET C=10
120 SCROLL
130 PRINT AT 9230;
140 IF PEEK ( PEEK oe M ыы F'
ЕЕК 16399)<125 THEN GOTO 220
150 PRINT "же
160, LET L=C
170 IF INKEY$ ="" THEN GOTO 190
180 LET Г-С- (C>1 AND INKEY$ ="1
"y+(C 212 AND ІМКЕҮФ ="0")
190 PRINT АТ 8» ЕМО *20; "m"
200 LET 3-241
210 PRINT AT Soli" "
220 GOTO 120
524
250
260
270
220
290
300
210
РЕІМТ 5
PAUSE 250
CLS
PRINT “PRESS NEWLINE FOR"
PRINT "ANOTHER GAME"
INFLIT A$
IF AS="" THEN GOTO ВО
525
Peter Morse is Professor and Head of Computer Science at the
Polytechnic of Central London. He has wide ranging teaching,
research and consultant activities in the fields of digital
systems, software engineering and computer education.
Ian Adamson is an educational consultant active in the design
of technical and scientific courses, and the associated buildings,
laboratories and equipment, working mainly on overseas
projects.
Ben Anrep is a Senior Programmer working оп
microprocessor system development and software with the
Computer Centre of the PCL.
Brian Hancock is Senior Lecturer in Computer Science. His
teaching and research activities include programming methods
and the operation of computer courses for schoolteachers.
The Essential Guide to Timex/Sinclair Home Computers is the only
comprehensive guide to the world's best-selling and most inexpensive
home computer, the Timex/Sinclair 1000 (also known as the Sinclair
ZX81) and the new Timex/Sinciair 2000. The authors, highly respected
computer science prolessors and consultants, take you beyond any
instruction manual and present everything you need to know, in easy-
to-understand language, about hardware, software and programming
skills. The Essential Guide to Timex/Sinclair Home Computers covers
all aspects of operating and programming Timex/Sinclair home com-
puters, including: turning the machine on (not as obvious as you
think!); the basics and the five points of Sinclair BASIC; designing
programs incorporating subroutines, loops and nested loops; using
strings, lists and arrays; generating graphics on the T/S 1000 and color
graphics on the T/S 2000; addressing the computers memory with
PEEK and POKE commands; and special tips on editing and debugging
techniques. It also includes a complete program library, as well as
many exercise and game programs to use while you learn, a section
on applications, a simple guide to error codes, a special summary of
Sinclair BASIC commands, an expianation of character sets and codes,
and much more. This is the oniy book you will ever need for your
Timex/Sinclair 1000 or 2000, and the perfect tool for building program-
ming confidence no matter what kind of computer you own.
oe Д |01/005і0Пе Book Cover by Zimmerman
Я Published by Simon & Schuster, Inc. Foyster Design
New York
“Timex” is a trademark of Timex Computer Corporation. “Sinclair” is a trademark of Sinclair
Research Ltd. Neither the author nor the publisher is affiliated with Timex Computer Corpora-
tion or Sinclair Research Ltd., and neither Timex Computer Corporation nor Sinclair Research
Ltd. has authorized the publication of this book.
0553-0550 $8.95 0-671-47069-8